/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved. 
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0  
 
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
MERCHANTABLITY OR NON-INFRINGEMENT. 
 
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var ts;
(function (ts) {
    // token > SyntaxKind.Identifer => token is a keyword
    // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
    var SyntaxKind;
    (function (SyntaxKind) {
        SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
        SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken";
        SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
        SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
        SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
        SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
        // We detect and preserve #! on the first line
        SyntaxKind[SyntaxKind["ShebangTrivia"] = 6] = "ShebangTrivia";
        // We detect and provide better error recovery when we encounter a git merge marker.  This
        // allows us to edit files with git-conflict markers in them in a much more pleasant manner.
        SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 7] = "ConflictMarkerTrivia";
        // Literals
        SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral";
        SyntaxKind[SyntaxKind["StringLiteral"] = 9] = "StringLiteral";
        SyntaxKind[SyntaxKind["JsxText"] = 10] = "JsxText";
        SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 11] = "JsxTextAllWhiteSpaces";
        SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 12] = "RegularExpressionLiteral";
        SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 13] = "NoSubstitutionTemplateLiteral";
        // Pseudo-literals
        SyntaxKind[SyntaxKind["TemplateHead"] = 14] = "TemplateHead";
        SyntaxKind[SyntaxKind["TemplateMiddle"] = 15] = "TemplateMiddle";
        SyntaxKind[SyntaxKind["TemplateTail"] = 16] = "TemplateTail";
        // Punctuation
        SyntaxKind[SyntaxKind["OpenBraceToken"] = 17] = "OpenBraceToken";
        SyntaxKind[SyntaxKind["CloseBraceToken"] = 18] = "CloseBraceToken";
        SyntaxKind[SyntaxKind["OpenParenToken"] = 19] = "OpenParenToken";
        SyntaxKind[SyntaxKind["CloseParenToken"] = 20] = "CloseParenToken";
        SyntaxKind[SyntaxKind["OpenBracketToken"] = 21] = "OpenBracketToken";
        SyntaxKind[SyntaxKind["CloseBracketToken"] = 22] = "CloseBracketToken";
        SyntaxKind[SyntaxKind["DotToken"] = 23] = "DotToken";
        SyntaxKind[SyntaxKind["DotDotDotToken"] = 24] = "DotDotDotToken";
        SyntaxKind[SyntaxKind["SemicolonToken"] = 25] = "SemicolonToken";
        SyntaxKind[SyntaxKind["CommaToken"] = 26] = "CommaToken";
        SyntaxKind[SyntaxKind["LessThanToken"] = 27] = "LessThanToken";
        SyntaxKind[SyntaxKind["LessThanSlashToken"] = 28] = "LessThanSlashToken";
        SyntaxKind[SyntaxKind["GreaterThanToken"] = 29] = "GreaterThanToken";
        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 30] = "LessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 31] = "GreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 32] = "EqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 33] = "ExclamationEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 34] = "EqualsEqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 35] = "ExclamationEqualsEqualsToken";
        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 36] = "EqualsGreaterThanToken";
        SyntaxKind[SyntaxKind["PlusToken"] = 37] = "PlusToken";
        SyntaxKind[SyntaxKind["MinusToken"] = 38] = "MinusToken";
        SyntaxKind[SyntaxKind["AsteriskToken"] = 39] = "AsteriskToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 40] = "AsteriskAsteriskToken";
        SyntaxKind[SyntaxKind["SlashToken"] = 41] = "SlashToken";
        SyntaxKind[SyntaxKind["PercentToken"] = 42] = "PercentToken";
        SyntaxKind[SyntaxKind["PlusPlusToken"] = 43] = "PlusPlusToken";
        SyntaxKind[SyntaxKind["MinusMinusToken"] = 44] = "MinusMinusToken";
        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 45] = "LessThanLessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 46] = "GreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 47] = "GreaterThanGreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["AmpersandToken"] = 48] = "AmpersandToken";
        SyntaxKind[SyntaxKind["BarToken"] = 49] = "BarToken";
        SyntaxKind[SyntaxKind["CaretToken"] = 50] = "CaretToken";
        SyntaxKind[SyntaxKind["ExclamationToken"] = 51] = "ExclamationToken";
        SyntaxKind[SyntaxKind["TildeToken"] = 52] = "TildeToken";
        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 53] = "AmpersandAmpersandToken";
        SyntaxKind[SyntaxKind["BarBarToken"] = 54] = "BarBarToken";
        SyntaxKind[SyntaxKind["QuestionToken"] = 55] = "QuestionToken";
        SyntaxKind[SyntaxKind["ColonToken"] = 56] = "ColonToken";
        SyntaxKind[SyntaxKind["AtToken"] = 57] = "AtToken";
        // Assignments
        SyntaxKind[SyntaxKind["EqualsToken"] = 58] = "EqualsToken";
        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 59] = "PlusEqualsToken";
        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 60] = "MinusEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 61] = "AsteriskEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 62] = "AsteriskAsteriskEqualsToken";
        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 63] = "SlashEqualsToken";
        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 64] = "PercentEqualsToken";
        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 65] = "LessThanLessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 66] = "GreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 67] = "GreaterThanGreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 68] = "AmpersandEqualsToken";
        SyntaxKind[SyntaxKind["BarEqualsToken"] = 69] = "BarEqualsToken";
        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 70] = "CaretEqualsToken";
        // Identifiers
        SyntaxKind[SyntaxKind["Identifier"] = 71] = "Identifier";
        // Reserved words
        SyntaxKind[SyntaxKind["BreakKeyword"] = 72] = "BreakKeyword";
        SyntaxKind[SyntaxKind["CaseKeyword"] = 73] = "CaseKeyword";
        SyntaxKind[SyntaxKind["CatchKeyword"] = 74] = "CatchKeyword";
        SyntaxKind[SyntaxKind["ClassKeyword"] = 75] = "ClassKeyword";
        SyntaxKind[SyntaxKind["ConstKeyword"] = 76] = "ConstKeyword";
        SyntaxKind[SyntaxKind["ContinueKeyword"] = 77] = "ContinueKeyword";
        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 78] = "DebuggerKeyword";
        SyntaxKind[SyntaxKind["DefaultKeyword"] = 79] = "DefaultKeyword";
        SyntaxKind[SyntaxKind["DeleteKeyword"] = 80] = "DeleteKeyword";
        SyntaxKind[SyntaxKind["DoKeyword"] = 81] = "DoKeyword";
        SyntaxKind[SyntaxKind["ElseKeyword"] = 82] = "ElseKeyword";
        SyntaxKind[SyntaxKind["EnumKeyword"] = 83] = "EnumKeyword";
        SyntaxKind[SyntaxKind["ExportKeyword"] = 84] = "ExportKeyword";
        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 85] = "ExtendsKeyword";
        SyntaxKind[SyntaxKind["FalseKeyword"] = 86] = "FalseKeyword";
        SyntaxKind[SyntaxKind["FinallyKeyword"] = 87] = "FinallyKeyword";
        SyntaxKind[SyntaxKind["ForKeyword"] = 88] = "ForKeyword";
        SyntaxKind[SyntaxKind["FunctionKeyword"] = 89] = "FunctionKeyword";
        SyntaxKind[SyntaxKind["IfKeyword"] = 90] = "IfKeyword";
        SyntaxKind[SyntaxKind["ImportKeyword"] = 91] = "ImportKeyword";
        SyntaxKind[SyntaxKind["InKeyword"] = 92] = "InKeyword";
        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 93] = "InstanceOfKeyword";
        SyntaxKind[SyntaxKind["NewKeyword"] = 94] = "NewKeyword";
        SyntaxKind[SyntaxKind["NullKeyword"] = 95] = "NullKeyword";
        SyntaxKind[SyntaxKind["ReturnKeyword"] = 96] = "ReturnKeyword";
        SyntaxKind[SyntaxKind["SuperKeyword"] = 97] = "SuperKeyword";
        SyntaxKind[SyntaxKind["SwitchKeyword"] = 98] = "SwitchKeyword";
        SyntaxKind[SyntaxKind["ThisKeyword"] = 99] = "ThisKeyword";
        SyntaxKind[SyntaxKind["ThrowKeyword"] = 100] = "ThrowKeyword";
        SyntaxKind[SyntaxKind["TrueKeyword"] = 101] = "TrueKeyword";
        SyntaxKind[SyntaxKind["TryKeyword"] = 102] = "TryKeyword";
        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 103] = "TypeOfKeyword";
        SyntaxKind[SyntaxKind["VarKeyword"] = 104] = "VarKeyword";
        SyntaxKind[SyntaxKind["VoidKeyword"] = 105] = "VoidKeyword";
        SyntaxKind[SyntaxKind["WhileKeyword"] = 106] = "WhileKeyword";
        SyntaxKind[SyntaxKind["WithKeyword"] = 107] = "WithKeyword";
        // Strict mode reserved words
        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 108] = "ImplementsKeyword";
        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 109] = "InterfaceKeyword";
        SyntaxKind[SyntaxKind["LetKeyword"] = 110] = "LetKeyword";
        SyntaxKind[SyntaxKind["PackageKeyword"] = 111] = "PackageKeyword";
        SyntaxKind[SyntaxKind["PrivateKeyword"] = 112] = "PrivateKeyword";
        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 113] = "ProtectedKeyword";
        SyntaxKind[SyntaxKind["PublicKeyword"] = 114] = "PublicKeyword";
        SyntaxKind[SyntaxKind["StaticKeyword"] = 115] = "StaticKeyword";
        SyntaxKind[SyntaxKind["YieldKeyword"] = 116] = "YieldKeyword";
        // Contextual keywords
        SyntaxKind[SyntaxKind["AbstractKeyword"] = 117] = "AbstractKeyword";
        SyntaxKind[SyntaxKind["AsKeyword"] = 118] = "AsKeyword";
        SyntaxKind[SyntaxKind["AnyKeyword"] = 119] = "AnyKeyword";
        SyntaxKind[SyntaxKind["AsyncKeyword"] = 120] = "AsyncKeyword";
        SyntaxKind[SyntaxKind["AwaitKeyword"] = 121] = "AwaitKeyword";
        SyntaxKind[SyntaxKind["BooleanKeyword"] = 122] = "BooleanKeyword";
        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 123] = "ConstructorKeyword";
        SyntaxKind[SyntaxKind["DeclareKeyword"] = 124] = "DeclareKeyword";
        SyntaxKind[SyntaxKind["GetKeyword"] = 125] = "GetKeyword";
        SyntaxKind[SyntaxKind["IsKeyword"] = 126] = "IsKeyword";
        SyntaxKind[SyntaxKind["KeyOfKeyword"] = 127] = "KeyOfKeyword";
        SyntaxKind[SyntaxKind["ModuleKeyword"] = 128] = "ModuleKeyword";
        SyntaxKind[SyntaxKind["NamespaceKeyword"] = 129] = "NamespaceKeyword";
        SyntaxKind[SyntaxKind["NeverKeyword"] = 130] = "NeverKeyword";
        SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 131] = "ReadonlyKeyword";
        SyntaxKind[SyntaxKind["RequireKeyword"] = 132] = "RequireKeyword";
        SyntaxKind[SyntaxKind["NumberKeyword"] = 133] = "NumberKeyword";
        SyntaxKind[SyntaxKind["ObjectKeyword"] = 134] = "ObjectKeyword";
        SyntaxKind[SyntaxKind["SetKeyword"] = 135] = "SetKeyword";
        SyntaxKind[SyntaxKind["StringKeyword"] = 136] = "StringKeyword";
        SyntaxKind[SyntaxKind["SymbolKeyword"] = 137] = "SymbolKeyword";
        SyntaxKind[SyntaxKind["TypeKeyword"] = 138] = "TypeKeyword";
        SyntaxKind[SyntaxKind["UndefinedKeyword"] = 139] = "UndefinedKeyword";
        SyntaxKind[SyntaxKind["FromKeyword"] = 140] = "FromKeyword";
        SyntaxKind[SyntaxKind["GlobalKeyword"] = 141] = "GlobalKeyword";
        SyntaxKind[SyntaxKind["OfKeyword"] = 142] = "OfKeyword";
        // Parse tree nodes
        // Names
        SyntaxKind[SyntaxKind["QualifiedName"] = 143] = "QualifiedName";
        SyntaxKind[SyntaxKind["ComputedPropertyName"] = 144] = "ComputedPropertyName";
        // Signature elements
        SyntaxKind[SyntaxKind["TypeParameter"] = 145] = "TypeParameter";
        SyntaxKind[SyntaxKind["Parameter"] = 146] = "Parameter";
        SyntaxKind[SyntaxKind["Decorator"] = 147] = "Decorator";
        // TypeMember
        SyntaxKind[SyntaxKind["PropertySignature"] = 148] = "PropertySignature";
        SyntaxKind[SyntaxKind["PropertyDeclaration"] = 149] = "PropertyDeclaration";
        SyntaxKind[SyntaxKind["MethodSignature"] = 150] = "MethodSignature";
        SyntaxKind[SyntaxKind["MethodDeclaration"] = 151] = "MethodDeclaration";
        SyntaxKind[SyntaxKind["Constructor"] = 152] = "Constructor";
        SyntaxKind[SyntaxKind["GetAccessor"] = 153] = "GetAccessor";
        SyntaxKind[SyntaxKind["SetAccessor"] = 154] = "SetAccessor";
        SyntaxKind[SyntaxKind["CallSignature"] = 155] = "CallSignature";
        SyntaxKind[SyntaxKind["ConstructSignature"] = 156] = "ConstructSignature";
        SyntaxKind[SyntaxKind["IndexSignature"] = 157] = "IndexSignature";
        // Type
        SyntaxKind[SyntaxKind["TypePredicate"] = 158] = "TypePredicate";
        SyntaxKind[SyntaxKind["TypeReference"] = 159] = "TypeReference";
        SyntaxKind[SyntaxKind["FunctionType"] = 160] = "FunctionType";
        SyntaxKind[SyntaxKind["ConstructorType"] = 161] = "ConstructorType";
        SyntaxKind[SyntaxKind["TypeQuery"] = 162] = "TypeQuery";
        SyntaxKind[SyntaxKind["TypeLiteral"] = 163] = "TypeLiteral";
        SyntaxKind[SyntaxKind["ArrayType"] = 164] = "ArrayType";
        SyntaxKind[SyntaxKind["TupleType"] = 165] = "TupleType";
        SyntaxKind[SyntaxKind["UnionType"] = 166] = "UnionType";
        SyntaxKind[SyntaxKind["IntersectionType"] = 167] = "IntersectionType";
        SyntaxKind[SyntaxKind["ParenthesizedType"] = 168] = "ParenthesizedType";
        SyntaxKind[SyntaxKind["ThisType"] = 169] = "ThisType";
        SyntaxKind[SyntaxKind["TypeOperator"] = 170] = "TypeOperator";
        SyntaxKind[SyntaxKind["IndexedAccessType"] = 171] = "IndexedAccessType";
        SyntaxKind[SyntaxKind["MappedType"] = 172] = "MappedType";
        SyntaxKind[SyntaxKind["LiteralType"] = 173] = "LiteralType";
        // Binding patterns
        SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 174] = "ObjectBindingPattern";
        SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 175] = "ArrayBindingPattern";
        SyntaxKind[SyntaxKind["BindingElement"] = 176] = "BindingElement";
        // Expression
        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 177] = "ArrayLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 178] = "ObjectLiteralExpression";
        SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 179] = "PropertyAccessExpression";
        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 180] = "ElementAccessExpression";
        SyntaxKind[SyntaxKind["CallExpression"] = 181] = "CallExpression";
        SyntaxKind[SyntaxKind["NewExpression"] = 182] = "NewExpression";
        SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 183] = "TaggedTemplateExpression";
        SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 184] = "TypeAssertionExpression";
        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 185] = "ParenthesizedExpression";
        SyntaxKind[SyntaxKind["FunctionExpression"] = 186] = "FunctionExpression";
        SyntaxKind[SyntaxKind["ArrowFunction"] = 187] = "ArrowFunction";
        SyntaxKind[SyntaxKind["DeleteExpression"] = 188] = "DeleteExpression";
        SyntaxKind[SyntaxKind["TypeOfExpression"] = 189] = "TypeOfExpression";
        SyntaxKind[SyntaxKind["VoidExpression"] = 190] = "VoidExpression";
        SyntaxKind[SyntaxKind["AwaitExpression"] = 191] = "AwaitExpression";
        SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 192] = "PrefixUnaryExpression";
        SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 193] = "PostfixUnaryExpression";
        SyntaxKind[SyntaxKind["BinaryExpression"] = 194] = "BinaryExpression";
        SyntaxKind[SyntaxKind["ConditionalExpression"] = 195] = "ConditionalExpression";
        SyntaxKind[SyntaxKind["TemplateExpression"] = 196] = "TemplateExpression";
        SyntaxKind[SyntaxKind["YieldExpression"] = 197] = "YieldExpression";
        SyntaxKind[SyntaxKind["SpreadElement"] = 198] = "SpreadElement";
        SyntaxKind[SyntaxKind["ClassExpression"] = 199] = "ClassExpression";
        SyntaxKind[SyntaxKind["OmittedExpression"] = 200] = "OmittedExpression";
        SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 201] = "ExpressionWithTypeArguments";
        SyntaxKind[SyntaxKind["AsExpression"] = 202] = "AsExpression";
        SyntaxKind[SyntaxKind["NonNullExpression"] = 203] = "NonNullExpression";
        SyntaxKind[SyntaxKind["MetaProperty"] = 204] = "MetaProperty";
        // Misc
        SyntaxKind[SyntaxKind["TemplateSpan"] = 205] = "TemplateSpan";
        SyntaxKind[SyntaxKind["SemicolonClassElement"] = 206] = "SemicolonClassElement";
        // Element
        SyntaxKind[SyntaxKind["Block"] = 207] = "Block";
        SyntaxKind[SyntaxKind["VariableStatement"] = 208] = "VariableStatement";
        SyntaxKind[SyntaxKind["EmptyStatement"] = 209] = "EmptyStatement";
        SyntaxKind[SyntaxKind["ExpressionStatement"] = 210] = "ExpressionStatement";
        SyntaxKind[SyntaxKind["IfStatement"] = 211] = "IfStatement";
        SyntaxKind[SyntaxKind["DoStatement"] = 212] = "DoStatement";
        SyntaxKind[SyntaxKind["WhileStatement"] = 213] = "WhileStatement";
        SyntaxKind[SyntaxKind["ForStatement"] = 214] = "ForStatement";
        SyntaxKind[SyntaxKind["ForInStatement"] = 215] = "ForInStatement";
        SyntaxKind[SyntaxKind["ForOfStatement"] = 216] = "ForOfStatement";
        SyntaxKind[SyntaxKind["ContinueStatement"] = 217] = "ContinueStatement";
        SyntaxKind[SyntaxKind["BreakStatement"] = 218] = "BreakStatement";
        SyntaxKind[SyntaxKind["ReturnStatement"] = 219] = "ReturnStatement";
        SyntaxKind[SyntaxKind["WithStatement"] = 220] = "WithStatement";
        SyntaxKind[SyntaxKind["SwitchStatement"] = 221] = "SwitchStatement";
        SyntaxKind[SyntaxKind["LabeledStatement"] = 222] = "LabeledStatement";
        SyntaxKind[SyntaxKind["ThrowStatement"] = 223] = "ThrowStatement";
        SyntaxKind[SyntaxKind["TryStatement"] = 224] = "TryStatement";
        SyntaxKind[SyntaxKind["DebuggerStatement"] = 225] = "DebuggerStatement";
        SyntaxKind[SyntaxKind["VariableDeclaration"] = 226] = "VariableDeclaration";
        SyntaxKind[SyntaxKind["VariableDeclarationList"] = 227] = "VariableDeclarationList";
        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 228] = "FunctionDeclaration";
        SyntaxKind[SyntaxKind["ClassDeclaration"] = 229] = "ClassDeclaration";
        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 230] = "InterfaceDeclaration";
        SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 231] = "TypeAliasDeclaration";
        SyntaxKind[SyntaxKind["EnumDeclaration"] = 232] = "EnumDeclaration";
        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 233] = "ModuleDeclaration";
        SyntaxKind[SyntaxKind["ModuleBlock"] = 234] = "ModuleBlock";
        SyntaxKind[SyntaxKind["CaseBlock"] = 235] = "CaseBlock";
        SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 236] = "NamespaceExportDeclaration";
        SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 237] = "ImportEqualsDeclaration";
        SyntaxKind[SyntaxKind["ImportDeclaration"] = 238] = "ImportDeclaration";
        SyntaxKind[SyntaxKind["ImportClause"] = 239] = "ImportClause";
        SyntaxKind[SyntaxKind["NamespaceImport"] = 240] = "NamespaceImport";
        SyntaxKind[SyntaxKind["NamedImports"] = 241] = "NamedImports";
        SyntaxKind[SyntaxKind["ImportSpecifier"] = 242] = "ImportSpecifier";
        SyntaxKind[SyntaxKind["ExportAssignment"] = 243] = "ExportAssignment";
        SyntaxKind[SyntaxKind["ExportDeclaration"] = 244] = "ExportDeclaration";
        SyntaxKind[SyntaxKind["NamedExports"] = 245] = "NamedExports";
        SyntaxKind[SyntaxKind["ExportSpecifier"] = 246] = "ExportSpecifier";
        SyntaxKind[SyntaxKind["MissingDeclaration"] = 247] = "MissingDeclaration";
        // Module references
        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 248] = "ExternalModuleReference";
        // JSX
        SyntaxKind[SyntaxKind["JsxElement"] = 249] = "JsxElement";
        SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 250] = "JsxSelfClosingElement";
        SyntaxKind[SyntaxKind["JsxOpeningElement"] = 251] = "JsxOpeningElement";
        SyntaxKind[SyntaxKind["JsxClosingElement"] = 252] = "JsxClosingElement";
        SyntaxKind[SyntaxKind["JsxAttribute"] = 253] = "JsxAttribute";
        SyntaxKind[SyntaxKind["JsxAttributes"] = 254] = "JsxAttributes";
        SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 255] = "JsxSpreadAttribute";
        SyntaxKind[SyntaxKind["JsxExpression"] = 256] = "JsxExpression";
        // Clauses
        SyntaxKind[SyntaxKind["CaseClause"] = 257] = "CaseClause";
        SyntaxKind[SyntaxKind["DefaultClause"] = 258] = "DefaultClause";
        SyntaxKind[SyntaxKind["HeritageClause"] = 259] = "HeritageClause";
        SyntaxKind[SyntaxKind["CatchClause"] = 260] = "CatchClause";
        // Property assignments
        SyntaxKind[SyntaxKind["PropertyAssignment"] = 261] = "PropertyAssignment";
        SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 262] = "ShorthandPropertyAssignment";
        SyntaxKind[SyntaxKind["SpreadAssignment"] = 263] = "SpreadAssignment";
        // Enum
        SyntaxKind[SyntaxKind["EnumMember"] = 264] = "EnumMember";
        // Top-level nodes
        SyntaxKind[SyntaxKind["SourceFile"] = 265] = "SourceFile";
        SyntaxKind[SyntaxKind["Bundle"] = 266] = "Bundle";
        // JSDoc nodes
        SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 267] = "JSDocTypeExpression";
        // The * type
        SyntaxKind[SyntaxKind["JSDocAllType"] = 268] = "JSDocAllType";
        // The ? type
        SyntaxKind[SyntaxKind["JSDocUnknownType"] = 269] = "JSDocUnknownType";
        SyntaxKind[SyntaxKind["JSDocNullableType"] = 270] = "JSDocNullableType";
        SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 271] = "JSDocNonNullableType";
        SyntaxKind[SyntaxKind["JSDocOptionalType"] = 272] = "JSDocOptionalType";
        SyntaxKind[SyntaxKind["JSDocFunctionType"] = 273] = "JSDocFunctionType";
        SyntaxKind[SyntaxKind["JSDocVariadicType"] = 274] = "JSDocVariadicType";
        SyntaxKind[SyntaxKind["JSDocComment"] = 275] = "JSDocComment";
        SyntaxKind[SyntaxKind["JSDocTag"] = 276] = "JSDocTag";
        SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 277] = "JSDocAugmentsTag";
        SyntaxKind[SyntaxKind["JSDocClassTag"] = 278] = "JSDocClassTag";
        SyntaxKind[SyntaxKind["JSDocParameterTag"] = 279] = "JSDocParameterTag";
        SyntaxKind[SyntaxKind["JSDocReturnTag"] = 280] = "JSDocReturnTag";
        SyntaxKind[SyntaxKind["JSDocTypeTag"] = 281] = "JSDocTypeTag";
        SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 282] = "JSDocTemplateTag";
        SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 283] = "JSDocTypedefTag";
        SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 284] = "JSDocPropertyTag";
        SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 285] = "JSDocTypeLiteral";
        // Synthesized list
        SyntaxKind[SyntaxKind["SyntaxList"] = 286] = "SyntaxList";
        // Transformation nodes
        SyntaxKind[SyntaxKind["NotEmittedStatement"] = 287] = "NotEmittedStatement";
        SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 288] = "PartiallyEmittedExpression";
        SyntaxKind[SyntaxKind["CommaListExpression"] = 289] = "CommaListExpression";
        SyntaxKind[SyntaxKind["MergeDeclarationMarker"] = 290] = "MergeDeclarationMarker";
        SyntaxKind[SyntaxKind["EndOfDeclarationMarker"] = 291] = "EndOfDeclarationMarker";
        // Enum value count
        SyntaxKind[SyntaxKind["Count"] = 292] = "Count";
        // Markers
        SyntaxKind[SyntaxKind["FirstAssignment"] = 58] = "FirstAssignment";
        SyntaxKind[SyntaxKind["LastAssignment"] = 70] = "LastAssignment";
        SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 59] = "FirstCompoundAssignment";
        SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 70] = "LastCompoundAssignment";
        SyntaxKind[SyntaxKind["FirstReservedWord"] = 72] = "FirstReservedWord";
        SyntaxKind[SyntaxKind["LastReservedWord"] = 107] = "LastReservedWord";
        SyntaxKind[SyntaxKind["FirstKeyword"] = 72] = "FirstKeyword";
        SyntaxKind[SyntaxKind["LastKeyword"] = 142] = "LastKeyword";
        SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 108] = "FirstFutureReservedWord";
        SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 116] = "LastFutureReservedWord";
        SyntaxKind[SyntaxKind["FirstTypeNode"] = 158] = "FirstTypeNode";
        SyntaxKind[SyntaxKind["LastTypeNode"] = 173] = "LastTypeNode";
        SyntaxKind[SyntaxKind["FirstPunctuation"] = 17] = "FirstPunctuation";
        SyntaxKind[SyntaxKind["LastPunctuation"] = 70] = "LastPunctuation";
        SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
        SyntaxKind[SyntaxKind["LastToken"] = 142] = "LastToken";
        SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
        SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken";
        SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
        SyntaxKind[SyntaxKind["LastLiteralToken"] = 13] = "LastLiteralToken";
        SyntaxKind[SyntaxKind["FirstTemplateToken"] = 13] = "FirstTemplateToken";
        SyntaxKind[SyntaxKind["LastTemplateToken"] = 16] = "LastTemplateToken";
        SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 27] = "FirstBinaryOperator";
        SyntaxKind[SyntaxKind["LastBinaryOperator"] = 70] = "LastBinaryOperator";
        SyntaxKind[SyntaxKind["FirstNode"] = 143] = "FirstNode";
        SyntaxKind[SyntaxKind["FirstJSDocNode"] = 267] = "FirstJSDocNode";
        SyntaxKind[SyntaxKind["LastJSDocNode"] = 285] = "LastJSDocNode";
        SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 276] = "FirstJSDocTagNode";
        SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 285] = "LastJSDocTagNode";
    })(SyntaxKind = ts.SyntaxKind || (ts.SyntaxKind = {}));
    var NodeFlags;
    (function (NodeFlags) {
        NodeFlags[NodeFlags["None"] = 0] = "None";
        NodeFlags[NodeFlags["Let"] = 1] = "Let";
        NodeFlags[NodeFlags["Const"] = 2] = "Const";
        NodeFlags[NodeFlags["NestedNamespace"] = 4] = "NestedNamespace";
        NodeFlags[NodeFlags["Synthesized"] = 8] = "Synthesized";
        NodeFlags[NodeFlags["Namespace"] = 16] = "Namespace";
        NodeFlags[NodeFlags["ExportContext"] = 32] = "ExportContext";
        NodeFlags[NodeFlags["ContainsThis"] = 64] = "ContainsThis";
        NodeFlags[NodeFlags["HasImplicitReturn"] = 128] = "HasImplicitReturn";
        NodeFlags[NodeFlags["HasExplicitReturn"] = 256] = "HasExplicitReturn";
        NodeFlags[NodeFlags["GlobalAugmentation"] = 512] = "GlobalAugmentation";
        NodeFlags[NodeFlags["HasAsyncFunctions"] = 1024] = "HasAsyncFunctions";
        NodeFlags[NodeFlags["DisallowInContext"] = 2048] = "DisallowInContext";
        NodeFlags[NodeFlags["YieldContext"] = 4096] = "YieldContext";
        NodeFlags[NodeFlags["DecoratorContext"] = 8192] = "DecoratorContext";
        NodeFlags[NodeFlags["AwaitContext"] = 16384] = "AwaitContext";
        NodeFlags[NodeFlags["ThisNodeHasError"] = 32768] = "ThisNodeHasError";
        NodeFlags[NodeFlags["JavaScriptFile"] = 65536] = "JavaScriptFile";
        NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 131072] = "ThisNodeOrAnySubNodesHasError";
        NodeFlags[NodeFlags["HasAggregatedChildData"] = 262144] = "HasAggregatedChildData";
        // This flag will be set when the parser encounters a dynamic import expression so that module resolution
        // will not have to walk the tree if the flag is not set. However, this flag is just a approximation because
        // once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport").
        // During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed
        // during module resolution. However, the removal operation should not occur often and in the case of the
        // removal, it is likely that users will add the import anyway.
        // The advantage of this approach is its simplicity. For the case of batch compilation,
        // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
        /* @internal */
        NodeFlags[NodeFlags["PossiblyContainsDynamicImport"] = 524288] = "PossiblyContainsDynamicImport";
        NodeFlags[NodeFlags["JSDoc"] = 1048576] = "JSDoc";
        NodeFlags[NodeFlags["BlockScoped"] = 3] = "BlockScoped";
        NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 384] = "ReachabilityCheckFlags";
        NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 1408] = "ReachabilityAndEmitFlags";
        // Parsing context flags
        NodeFlags[NodeFlags["ContextFlags"] = 96256] = "ContextFlags";
        // Exclude these flags when parsing a Type
        NodeFlags[NodeFlags["TypeExcludesFlags"] = 20480] = "TypeExcludesFlags";
    })(NodeFlags = ts.NodeFlags || (ts.NodeFlags = {}));
    var ModifierFlags;
    (function (ModifierFlags) {
        ModifierFlags[ModifierFlags["None"] = 0] = "None";
        ModifierFlags[ModifierFlags["Export"] = 1] = "Export";
        ModifierFlags[ModifierFlags["Ambient"] = 2] = "Ambient";
        ModifierFlags[ModifierFlags["Public"] = 4] = "Public";
        ModifierFlags[ModifierFlags["Private"] = 8] = "Private";
        ModifierFlags[ModifierFlags["Protected"] = 16] = "Protected";
        ModifierFlags[ModifierFlags["Static"] = 32] = "Static";
        ModifierFlags[ModifierFlags["Readonly"] = 64] = "Readonly";
        ModifierFlags[ModifierFlags["Abstract"] = 128] = "Abstract";
        ModifierFlags[ModifierFlags["Async"] = 256] = "Async";
        ModifierFlags[ModifierFlags["Default"] = 512] = "Default";
        ModifierFlags[ModifierFlags["Const"] = 2048] = "Const";
        ModifierFlags[ModifierFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        ModifierFlags[ModifierFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier";
        // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
        ModifierFlags[ModifierFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier";
        ModifierFlags[ModifierFlags["NonPublicAccessibilityModifier"] = 24] = "NonPublicAccessibilityModifier";
        ModifierFlags[ModifierFlags["TypeScriptModifier"] = 2270] = "TypeScriptModifier";
        ModifierFlags[ModifierFlags["ExportDefault"] = 513] = "ExportDefault";
    })(ModifierFlags = ts.ModifierFlags || (ts.ModifierFlags = {}));
    var JsxFlags;
    (function (JsxFlags) {
        JsxFlags[JsxFlags["None"] = 0] = "None";
        /** An element from a named property of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicNamedElement"] = 1] = "IntrinsicNamedElement";
        /** An element inferred from the string index signature of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicIndexedElement"] = 2] = "IntrinsicIndexedElement";
        JsxFlags[JsxFlags["IntrinsicElement"] = 3] = "IntrinsicElement";
    })(JsxFlags = ts.JsxFlags || (ts.JsxFlags = {}));
    /* @internal */
    var RelationComparisonResult;
    (function (RelationComparisonResult) {
        RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded";
        RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed";
        RelationComparisonResult[RelationComparisonResult["FailedAndReported"] = 3] = "FailedAndReported";
    })(RelationComparisonResult = ts.RelationComparisonResult || (ts.RelationComparisonResult = {}));
    /*@internal*/
    var GeneratedIdentifierKind;
    (function (GeneratedIdentifierKind) {
        GeneratedIdentifierKind[GeneratedIdentifierKind["None"] = 0] = "None";
        GeneratedIdentifierKind[GeneratedIdentifierKind["Auto"] = 1] = "Auto";
        GeneratedIdentifierKind[GeneratedIdentifierKind["Loop"] = 2] = "Loop";
        GeneratedIdentifierKind[GeneratedIdentifierKind["Unique"] = 3] = "Unique";
        GeneratedIdentifierKind[GeneratedIdentifierKind["Node"] = 4] = "Node";
    })(GeneratedIdentifierKind = ts.GeneratedIdentifierKind || (ts.GeneratedIdentifierKind = {}));
    /* @internal */
    var NumericLiteralFlags;
    (function (NumericLiteralFlags) {
        NumericLiteralFlags[NumericLiteralFlags["None"] = 0] = "None";
        NumericLiteralFlags[NumericLiteralFlags["Scientific"] = 2] = "Scientific";
        NumericLiteralFlags[NumericLiteralFlags["Octal"] = 4] = "Octal";
        NumericLiteralFlags[NumericLiteralFlags["HexSpecifier"] = 8] = "HexSpecifier";
        NumericLiteralFlags[NumericLiteralFlags["BinarySpecifier"] = 16] = "BinarySpecifier";
        NumericLiteralFlags[NumericLiteralFlags["OctalSpecifier"] = 32] = "OctalSpecifier";
        NumericLiteralFlags[NumericLiteralFlags["BinaryOrOctalSpecifier"] = 48] = "BinaryOrOctalSpecifier";
    })(NumericLiteralFlags = ts.NumericLiteralFlags || (ts.NumericLiteralFlags = {}));
    var FlowFlags;
    (function (FlowFlags) {
        FlowFlags[FlowFlags["Unreachable"] = 1] = "Unreachable";
        FlowFlags[FlowFlags["Start"] = 2] = "Start";
        FlowFlags[FlowFlags["BranchLabel"] = 4] = "BranchLabel";
        FlowFlags[FlowFlags["LoopLabel"] = 8] = "LoopLabel";
        FlowFlags[FlowFlags["Assignment"] = 16] = "Assignment";
        FlowFlags[FlowFlags["TrueCondition"] = 32] = "TrueCondition";
        FlowFlags[FlowFlags["FalseCondition"] = 64] = "FalseCondition";
        FlowFlags[FlowFlags["SwitchClause"] = 128] = "SwitchClause";
        FlowFlags[FlowFlags["ArrayMutation"] = 256] = "ArrayMutation";
        FlowFlags[FlowFlags["Referenced"] = 512] = "Referenced";
        FlowFlags[FlowFlags["Shared"] = 1024] = "Shared";
        FlowFlags[FlowFlags["PreFinally"] = 2048] = "PreFinally";
        FlowFlags[FlowFlags["AfterFinally"] = 4096] = "AfterFinally";
        FlowFlags[FlowFlags["Label"] = 12] = "Label";
        FlowFlags[FlowFlags["Condition"] = 96] = "Condition";
    })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {}));
    var OperationCanceledException = /** @class */ (function () {
        function OperationCanceledException() {
        }
        return OperationCanceledException;
    }());
    ts.OperationCanceledException = OperationCanceledException;
    /* @internal */
    var StructureIsReused;
    (function (StructureIsReused) {
        StructureIsReused[StructureIsReused["Not"] = 0] = "Not";
        StructureIsReused[StructureIsReused["SafeModules"] = 1] = "SafeModules";
        StructureIsReused[StructureIsReused["Completely"] = 2] = "Completely";
    })(StructureIsReused = ts.StructureIsReused || (ts.StructureIsReused = {}));
    /** Return code used by getEmitOutput function to indicate status of the function */
    var ExitStatus;
    (function (ExitStatus) {
        // Compiler ran successfully.  Either this was a simple do-nothing compilation (for example,
        // when -version or -help was provided, or this was a normal compilation, no diagnostics
        // were produced, and all outputs were generated successfully.
        ExitStatus[ExitStatus["Success"] = 0] = "Success";
        // Diagnostics were produced and because of them no code was generated.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsSkipped"] = 1] = "DiagnosticsPresent_OutputsSkipped";
        // Diagnostics were produced and outputs were generated in spite of them.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsGenerated"] = 2] = "DiagnosticsPresent_OutputsGenerated";
    })(ExitStatus = ts.ExitStatus || (ts.ExitStatus = {}));
    var NodeBuilderFlags;
    (function (NodeBuilderFlags) {
        NodeBuilderFlags[NodeBuilderFlags["None"] = 0] = "None";
        // Options
        NodeBuilderFlags[NodeBuilderFlags["NoTruncation"] = 1] = "NoTruncation";
        NodeBuilderFlags[NodeBuilderFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        NodeBuilderFlags[NodeBuilderFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        NodeBuilderFlags[NodeBuilderFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeParametersInQualifiedName"] = 512] = "WriteTypeParametersInQualifiedName";
        // Error handling
        NodeBuilderFlags[NodeBuilderFlags["AllowThisInObjectLiteral"] = 1024] = "AllowThisInObjectLiteral";
        NodeBuilderFlags[NodeBuilderFlags["AllowQualifedNameInPlaceOfIdentifier"] = 2048] = "AllowQualifedNameInPlaceOfIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowAnonymousIdentifier"] = 8192] = "AllowAnonymousIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyUnionOrIntersection"] = 16384] = "AllowEmptyUnionOrIntersection";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyTuple"] = 32768] = "AllowEmptyTuple";
        NodeBuilderFlags[NodeBuilderFlags["IgnoreErrors"] = 60416] = "IgnoreErrors";
        // State
        NodeBuilderFlags[NodeBuilderFlags["InObjectTypeLiteral"] = 1048576] = "InObjectTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
    })(NodeBuilderFlags = ts.NodeBuilderFlags || (ts.NodeBuilderFlags = {}));
    var TypeFormatFlags;
    (function (TypeFormatFlags) {
        TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
        TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 1] = "WriteArrayAsGenericType";
        TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 4] = "UseTypeOfFunction";
        TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 8] = "NoTruncation";
        TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 16] = "WriteArrowStyleSignature";
        TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 32] = "WriteOwnNameForAnyLike";
        TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 64] = "WriteTypeArgumentsOfSignature";
        TypeFormatFlags[TypeFormatFlags["InElementType"] = 128] = "InElementType";
        TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 256] = "UseFullyQualifiedType";
        TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 512] = "InFirstTypeArgument";
        TypeFormatFlags[TypeFormatFlags["InTypeAlias"] = 1024] = "InTypeAlias";
        TypeFormatFlags[TypeFormatFlags["SuppressAnyReturnType"] = 4096] = "SuppressAnyReturnType";
        TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined";
        TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral";
        TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType";
        TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope";
        // even though `T` can't be accessed in the current scope.
    })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
    var SymbolFormatFlags;
    (function (SymbolFormatFlags) {
        SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None";
        // Write symbols's type argument if it is instantiated symbol
        // eg. class C<T> { p: T }   <-- Show p as C<T>.p here
        //     var a: C<number>;
        //     var p = a.p;  <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
        SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments";
        // Use only external alias information to get the symbol name in the given context
        // eg.  module m { export class c { } } import x = m.c;
        // When this flag is specified m.c will be used to refer to the class instead of alias symbol x
        SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing";
    })(SymbolFormatFlags = ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
    /* @internal */
    var SymbolAccessibility;
    (function (SymbolAccessibility) {
        SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
        SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
        SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
    })(SymbolAccessibility = ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
    /* @internal */
    var SyntheticSymbolKind;
    (function (SyntheticSymbolKind) {
        SyntheticSymbolKind[SyntheticSymbolKind["UnionOrIntersection"] = 0] = "UnionOrIntersection";
        SyntheticSymbolKind[SyntheticSymbolKind["Spread"] = 1] = "Spread";
    })(SyntheticSymbolKind = ts.SyntheticSymbolKind || (ts.SyntheticSymbolKind = {}));
    var TypePredicateKind;
    (function (TypePredicateKind) {
        TypePredicateKind[TypePredicateKind["This"] = 0] = "This";
        TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier";
    })(TypePredicateKind = ts.TypePredicateKind || (ts.TypePredicateKind = {}));
    /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
    /* @internal */
    var TypeReferenceSerializationKind;
    (function (TypeReferenceSerializationKind) {
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Unknown"] = 0] = "Unknown";
        // should be emitted using a safe fallback.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithConstructSignatureAndValue"] = 1] = "TypeWithConstructSignatureAndValue";
        // function that can be reached at runtime (e.g. a `class`
        // declaration or a `var` declaration for the static side
        // of a type, such as the global `Promise` type in lib.d.ts).
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["VoidNullableOrNeverType"] = 2] = "VoidNullableOrNeverType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["NumberLikeType"] = 3] = "NumberLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["StringLikeType"] = 4] = "StringLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BooleanType"] = 5] = "BooleanType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ArrayLikeType"] = 6] = "ArrayLikeType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ESSymbolType"] = 7] = "ESSymbolType";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Promise"] = 8] = "Promise";
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithCallSignature"] = 9] = "TypeWithCallSignature";
        // with call signatures.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 10] = "ObjectType";
    })(TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {}));
    var SymbolFlags;
    (function (SymbolFlags) {
        SymbolFlags[SymbolFlags["None"] = 0] = "None";
        SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable";
        SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable";
        SymbolFlags[SymbolFlags["Property"] = 4] = "Property";
        SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember";
        SymbolFlags[SymbolFlags["Function"] = 16] = "Function";
        SymbolFlags[SymbolFlags["Class"] = 32] = "Class";
        SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface";
        SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum";
        SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum";
        SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule";
        SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule";
        SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral";
        SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral";
        SymbolFlags[SymbolFlags["Method"] = 8192] = "Method";
        SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor";
        SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor";
        SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor";
        SymbolFlags[SymbolFlags["Signature"] = 131072] = "Signature";
        SymbolFlags[SymbolFlags["TypeParameter"] = 262144] = "TypeParameter";
        SymbolFlags[SymbolFlags["TypeAlias"] = 524288] = "TypeAlias";
        SymbolFlags[SymbolFlags["ExportValue"] = 1048576] = "ExportValue";
        SymbolFlags[SymbolFlags["Alias"] = 2097152] = "Alias";
        SymbolFlags[SymbolFlags["Prototype"] = 4194304] = "Prototype";
        SymbolFlags[SymbolFlags["ExportStar"] = 8388608] = "ExportStar";
        SymbolFlags[SymbolFlags["Optional"] = 16777216] = "Optional";
        SymbolFlags[SymbolFlags["Transient"] = 33554432] = "Transient";
        SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
        SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
        SymbolFlags[SymbolFlags["Value"] = 107455] = "Value";
        SymbolFlags[SymbolFlags["Type"] = 793064] = "Type";
        SymbolFlags[SymbolFlags["Namespace"] = 1920] = "Namespace";
        SymbolFlags[SymbolFlags["Module"] = 1536] = "Module";
        SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor";
        // Variables can be redeclared, but can not redeclare a block-scoped declaration with the
        // same name, or any other value that is not a variable, e.g. ValueModule or Class
        SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 107454] = "FunctionScopedVariableExcludes";
        // Block-scoped declarations are not allowed to be re-declared
        // they can not merge with anything in the value space
        SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 107455] = "BlockScopedVariableExcludes";
        SymbolFlags[SymbolFlags["ParameterExcludes"] = 107455] = "ParameterExcludes";
        SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes";
        SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 900095] = "EnumMemberExcludes";
        SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes";
        SymbolFlags[SymbolFlags["ClassExcludes"] = 899519] = "ClassExcludes";
        SymbolFlags[SymbolFlags["InterfaceExcludes"] = 792968] = "InterfaceExcludes";
        SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 899327] = "RegularEnumExcludes";
        SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 899967] = "ConstEnumExcludes";
        SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 106639] = "ValueModuleExcludes";
        SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes";
        SymbolFlags[SymbolFlags["MethodExcludes"] = 99263] = "MethodExcludes";
        SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 41919] = "GetAccessorExcludes";
        SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 74687] = "SetAccessorExcludes";
        SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 530920] = "TypeParameterExcludes";
        SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 793064] = "TypeAliasExcludes";
        SymbolFlags[SymbolFlags["AliasExcludes"] = 2097152] = "AliasExcludes";
        SymbolFlags[SymbolFlags["ModuleMember"] = 2623475] = "ModuleMember";
        SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal";
        SymbolFlags[SymbolFlags["HasExports"] = 1952] = "HasExports";
        SymbolFlags[SymbolFlags["HasMembers"] = 6240] = "HasMembers";
        SymbolFlags[SymbolFlags["BlockScoped"] = 418] = "BlockScoped";
        SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor";
        SymbolFlags[SymbolFlags["ClassMember"] = 106500] = "ClassMember";
        /* @internal */
        // The set of things we consider semantically classifiable.  Used to speed up the LS during
        // classification.
        SymbolFlags[SymbolFlags["Classifiable"] = 788448] = "Classifiable";
    })(SymbolFlags = ts.SymbolFlags || (ts.SymbolFlags = {}));
    /* @internal */
    var EnumKind;
    (function (EnumKind) {
        EnumKind[EnumKind["Numeric"] = 0] = "Numeric";
        EnumKind[EnumKind["Literal"] = 1] = "Literal"; // Literal enum (each member has a TypeFlags.EnumLiteral type)
    })(EnumKind = ts.EnumKind || (ts.EnumKind = {}));
    /* @internal */
    var CheckFlags;
    (function (CheckFlags) {
        CheckFlags[CheckFlags["Instantiated"] = 1] = "Instantiated";
        CheckFlags[CheckFlags["SyntheticProperty"] = 2] = "SyntheticProperty";
        CheckFlags[CheckFlags["SyntheticMethod"] = 4] = "SyntheticMethod";
        CheckFlags[CheckFlags["Readonly"] = 8] = "Readonly";
        CheckFlags[CheckFlags["Partial"] = 16] = "Partial";
        CheckFlags[CheckFlags["HasNonUniformType"] = 32] = "HasNonUniformType";
        CheckFlags[CheckFlags["ContainsPublic"] = 64] = "ContainsPublic";
        CheckFlags[CheckFlags["ContainsProtected"] = 128] = "ContainsProtected";
        CheckFlags[CheckFlags["ContainsPrivate"] = 256] = "ContainsPrivate";
        CheckFlags[CheckFlags["ContainsStatic"] = 512] = "ContainsStatic";
        CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
    })(CheckFlags = ts.CheckFlags || (ts.CheckFlags = {}));
    var InternalSymbolName;
    (function (InternalSymbolName) {
        InternalSymbolName["Call"] = "__call";
        InternalSymbolName["Constructor"] = "__constructor";
        InternalSymbolName["New"] = "__new";
        InternalSymbolName["Index"] = "__index";
        InternalSymbolName["ExportStar"] = "__export";
        InternalSymbolName["Global"] = "__global";
        InternalSymbolName["Missing"] = "__missing";
        InternalSymbolName["Type"] = "__type";
        InternalSymbolName["Object"] = "__object";
        InternalSymbolName["JSXAttributes"] = "__jsxAttributes";
        InternalSymbolName["Class"] = "__class";
        InternalSymbolName["Function"] = "__function";
        InternalSymbolName["Computed"] = "__computed";
        InternalSymbolName["Resolving"] = "__resolving__";
        InternalSymbolName["ExportEquals"] = "export=";
        InternalSymbolName["Default"] = "default";
    })(InternalSymbolName = ts.InternalSymbolName || (ts.InternalSymbolName = {}));
    /* @internal */
    var NodeCheckFlags;
    (function (NodeCheckFlags) {
        NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
        NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
        NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
        NodeCheckFlags[NodeCheckFlags["CaptureNewTarget"] = 8] = "CaptureNewTarget";
        NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 256] = "SuperInstance";
        NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 512] = "SuperStatic";
        NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 1024] = "ContextChecked";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuper"] = 2048] = "AsyncMethodWithSuper";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuperBinding"] = 4096] = "AsyncMethodWithSuperBinding";
        NodeCheckFlags[NodeCheckFlags["CaptureArguments"] = 8192] = "CaptureArguments";
        NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 16384] = "EnumValuesComputed";
        NodeCheckFlags[NodeCheckFlags["LexicalModuleMergesWithClass"] = 32768] = "LexicalModuleMergesWithClass";
        NodeCheckFlags[NodeCheckFlags["LoopWithCapturedBlockScopedBinding"] = 65536] = "LoopWithCapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["CapturedBlockScopedBinding"] = 131072] = "CapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["BlockScopedBindingInLoop"] = 262144] = "BlockScopedBindingInLoop";
        NodeCheckFlags[NodeCheckFlags["ClassWithBodyScopedClassBinding"] = 524288] = "ClassWithBodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["BodyScopedClassBinding"] = 1048576] = "BodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["NeedsLoopOutParameter"] = 2097152] = "NeedsLoopOutParameter";
        NodeCheckFlags[NodeCheckFlags["AssignmentsMarked"] = 4194304] = "AssignmentsMarked";
        NodeCheckFlags[NodeCheckFlags["ClassWithConstructorReference"] = 8388608] = "ClassWithConstructorReference";
        NodeCheckFlags[NodeCheckFlags["ConstructorReferenceInClass"] = 16777216] = "ConstructorReferenceInClass";
    })(NodeCheckFlags = ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
    var TypeFlags;
    (function (TypeFlags) {
        TypeFlags[TypeFlags["Any"] = 1] = "Any";
        TypeFlags[TypeFlags["String"] = 2] = "String";
        TypeFlags[TypeFlags["Number"] = 4] = "Number";
        TypeFlags[TypeFlags["Boolean"] = 8] = "Boolean";
        TypeFlags[TypeFlags["Enum"] = 16] = "Enum";
        TypeFlags[TypeFlags["StringLiteral"] = 32] = "StringLiteral";
        TypeFlags[TypeFlags["NumberLiteral"] = 64] = "NumberLiteral";
        TypeFlags[TypeFlags["BooleanLiteral"] = 128] = "BooleanLiteral";
        TypeFlags[TypeFlags["EnumLiteral"] = 256] = "EnumLiteral";
        TypeFlags[TypeFlags["ESSymbol"] = 512] = "ESSymbol";
        TypeFlags[TypeFlags["Void"] = 1024] = "Void";
        TypeFlags[TypeFlags["Undefined"] = 2048] = "Undefined";
        TypeFlags[TypeFlags["Null"] = 4096] = "Null";
        TypeFlags[TypeFlags["Never"] = 8192] = "Never";
        TypeFlags[TypeFlags["TypeParameter"] = 16384] = "TypeParameter";
        TypeFlags[TypeFlags["Object"] = 32768] = "Object";
        TypeFlags[TypeFlags["Union"] = 65536] = "Union";
        TypeFlags[TypeFlags["Intersection"] = 131072] = "Intersection";
        TypeFlags[TypeFlags["Index"] = 262144] = "Index";
        TypeFlags[TypeFlags["IndexedAccess"] = 524288] = "IndexedAccess";
        /* @internal */
        TypeFlags[TypeFlags["FreshLiteral"] = 1048576] = "FreshLiteral";
        /* @internal */
        TypeFlags[TypeFlags["ContainsWideningType"] = 2097152] = "ContainsWideningType";
        /* @internal */
        TypeFlags[TypeFlags["ContainsObjectLiteral"] = 4194304] = "ContainsObjectLiteral";
        /* @internal */
        TypeFlags[TypeFlags["ContainsAnyFunctionType"] = 8388608] = "ContainsAnyFunctionType";
        TypeFlags[TypeFlags["NonPrimitive"] = 16777216] = "NonPrimitive";
        /* @internal */
        TypeFlags[TypeFlags["JsxAttributes"] = 33554432] = "JsxAttributes";
        TypeFlags[TypeFlags["MarkerType"] = 67108864] = "MarkerType";
        /* @internal */
        TypeFlags[TypeFlags["Nullable"] = 6144] = "Nullable";
        TypeFlags[TypeFlags["Literal"] = 224] = "Literal";
        TypeFlags[TypeFlags["Unit"] = 6368] = "Unit";
        TypeFlags[TypeFlags["StringOrNumberLiteral"] = 96] = "StringOrNumberLiteral";
        /* @internal */
        TypeFlags[TypeFlags["DefinitelyFalsy"] = 7392] = "DefinitelyFalsy";
        TypeFlags[TypeFlags["PossiblyFalsy"] = 7406] = "PossiblyFalsy";
        /* @internal */
        TypeFlags[TypeFlags["Intrinsic"] = 16793231] = "Intrinsic";
        /* @internal */
        TypeFlags[TypeFlags["Primitive"] = 8190] = "Primitive";
        TypeFlags[TypeFlags["StringLike"] = 262178] = "StringLike";
        TypeFlags[TypeFlags["NumberLike"] = 84] = "NumberLike";
        TypeFlags[TypeFlags["BooleanLike"] = 136] = "BooleanLike";
        TypeFlags[TypeFlags["EnumLike"] = 272] = "EnumLike";
        TypeFlags[TypeFlags["UnionOrIntersection"] = 196608] = "UnionOrIntersection";
        TypeFlags[TypeFlags["StructuredType"] = 229376] = "StructuredType";
        TypeFlags[TypeFlags["StructuredOrTypeVariable"] = 1032192] = "StructuredOrTypeVariable";
        TypeFlags[TypeFlags["TypeVariable"] = 540672] = "TypeVariable";
        // 'Narrowable' types are types where narrowing actually narrows.
        // This *should* be every type other than null, undefined, void, and never
        TypeFlags[TypeFlags["Narrowable"] = 17810175] = "Narrowable";
        TypeFlags[TypeFlags["NotUnionOrUnit"] = 16810497] = "NotUnionOrUnit";
        /* @internal */
        TypeFlags[TypeFlags["RequiresWidening"] = 6291456] = "RequiresWidening";
        /* @internal */
        TypeFlags[TypeFlags["PropagatingFlags"] = 14680064] = "PropagatingFlags";
    })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {}));
    var ObjectFlags;
    (function (ObjectFlags) {
        ObjectFlags[ObjectFlags["Class"] = 1] = "Class";
        ObjectFlags[ObjectFlags["Interface"] = 2] = "Interface";
        ObjectFlags[ObjectFlags["Reference"] = 4] = "Reference";
        ObjectFlags[ObjectFlags["Tuple"] = 8] = "Tuple";
        ObjectFlags[ObjectFlags["Anonymous"] = 16] = "Anonymous";
        ObjectFlags[ObjectFlags["Mapped"] = 32] = "Mapped";
        ObjectFlags[ObjectFlags["Instantiated"] = 64] = "Instantiated";
        ObjectFlags[ObjectFlags["ObjectLiteral"] = 128] = "ObjectLiteral";
        ObjectFlags[ObjectFlags["EvolvingArray"] = 256] = "EvolvingArray";
        ObjectFlags[ObjectFlags["ObjectLiteralPatternWithComputedProperties"] = 512] = "ObjectLiteralPatternWithComputedProperties";
        ObjectFlags[ObjectFlags["ClassOrInterface"] = 3] = "ClassOrInterface";
    })(ObjectFlags = ts.ObjectFlags || (ts.ObjectFlags = {}));
    /* @internal */
    var Variance;
    (function (Variance) {
        Variance[Variance["Invariant"] = 0] = "Invariant";
        Variance[Variance["Covariant"] = 1] = "Covariant";
        Variance[Variance["Contravariant"] = 2] = "Contravariant";
        Variance[Variance["Bivariant"] = 3] = "Bivariant";
        Variance[Variance["Independent"] = 4] = "Independent";
    })(Variance = ts.Variance || (ts.Variance = {}));
    var SignatureKind;
    (function (SignatureKind) {
        SignatureKind[SignatureKind["Call"] = 0] = "Call";
        SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
    })(SignatureKind = ts.SignatureKind || (ts.SignatureKind = {}));
    var IndexKind;
    (function (IndexKind) {
        IndexKind[IndexKind["String"] = 0] = "String";
        IndexKind[IndexKind["Number"] = 1] = "Number";
    })(IndexKind = ts.IndexKind || (ts.IndexKind = {}));
    var InferencePriority;
    (function (InferencePriority) {
        InferencePriority[InferencePriority["Contravariant"] = 1] = "Contravariant";
        InferencePriority[InferencePriority["NakedTypeVariable"] = 2] = "NakedTypeVariable";
        InferencePriority[InferencePriority["MappedType"] = 4] = "MappedType";
        InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType";
    })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {}));
    var InferenceFlags;
    (function (InferenceFlags) {
        InferenceFlags[InferenceFlags["InferUnionTypes"] = 1] = "InferUnionTypes";
        InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault";
        InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault";
    })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {}));
    /**
     * Ternary values are defined such that
     * x & y is False if either x or y is False.
     * x & y is Maybe if either x or y is Maybe, but neither x or y is False.
     * x & y is True if both x and y are True.
     * x | y is False if both x and y are False.
     * x | y is Maybe if either x or y is Maybe, but neither x or y is True.
     * x | y is True if either x or y is True.
     */
    var Ternary;
    (function (Ternary) {
        Ternary[Ternary["False"] = 0] = "False";
        Ternary[Ternary["Maybe"] = 1] = "Maybe";
        Ternary[Ternary["True"] = -1] = "True";
    })(Ternary = ts.Ternary || (ts.Ternary = {}));
    /* @internal */
    var SpecialPropertyAssignmentKind;
    (function (SpecialPropertyAssignmentKind) {
        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["None"] = 0] = "None";
        /// exports.name = expr
        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ExportsProperty"] = 1] = "ExportsProperty";
        /// module.exports = expr
        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ModuleExports"] = 2] = "ModuleExports";
        /// className.prototype.name = expr
        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["PrototypeProperty"] = 3] = "PrototypeProperty";
        /// this.name = expr
        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ThisProperty"] = 4] = "ThisProperty";
        // F.name = expr
        SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["Property"] = 5] = "Property";
    })(SpecialPropertyAssignmentKind = ts.SpecialPropertyAssignmentKind || (ts.SpecialPropertyAssignmentKind = {}));
    var DiagnosticCategory;
    (function (DiagnosticCategory) {
        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
        DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message";
    })(DiagnosticCategory = ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
    var ModuleResolutionKind;
    (function (ModuleResolutionKind) {
        ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic";
        ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs";
    })(ModuleResolutionKind = ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {}));
    var ModuleKind;
    (function (ModuleKind) {
        ModuleKind[ModuleKind["None"] = 0] = "None";
        ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS";
        ModuleKind[ModuleKind["AMD"] = 2] = "AMD";
        ModuleKind[ModuleKind["UMD"] = 3] = "UMD";
        ModuleKind[ModuleKind["System"] = 4] = "System";
        ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015";
        ModuleKind[ModuleKind["ESNext"] = 6] = "ESNext";
    })(ModuleKind = ts.ModuleKind || (ts.ModuleKind = {}));
    var JsxEmit;
    (function (JsxEmit) {
        JsxEmit[JsxEmit["None"] = 0] = "None";
        JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve";
        JsxEmit[JsxEmit["React"] = 2] = "React";
        JsxEmit[JsxEmit["ReactNative"] = 3] = "ReactNative";
    })(JsxEmit = ts.JsxEmit || (ts.JsxEmit = {}));
    var NewLineKind;
    (function (NewLineKind) {
        NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed";
        NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed";
    })(NewLineKind = ts.NewLineKind || (ts.NewLineKind = {}));
    var ScriptKind;
    (function (ScriptKind) {
        ScriptKind[ScriptKind["Unknown"] = 0] = "Unknown";
        ScriptKind[ScriptKind["JS"] = 1] = "JS";
        ScriptKind[ScriptKind["JSX"] = 2] = "JSX";
        ScriptKind[ScriptKind["TS"] = 3] = "TS";
        ScriptKind[ScriptKind["TSX"] = 4] = "TSX";
        ScriptKind[ScriptKind["External"] = 5] = "External";
        ScriptKind[ScriptKind["JSON"] = 6] = "JSON";
    })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {}));
    var ScriptTarget;
    (function (ScriptTarget) {
        ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
        ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
        ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015";
        ScriptTarget[ScriptTarget["ES2016"] = 3] = "ES2016";
        ScriptTarget[ScriptTarget["ES2017"] = 4] = "ES2017";
        ScriptTarget[ScriptTarget["ESNext"] = 5] = "ESNext";
        ScriptTarget[ScriptTarget["Latest"] = 5] = "Latest";
    })(ScriptTarget = ts.ScriptTarget || (ts.ScriptTarget = {}));
    var LanguageVariant;
    (function (LanguageVariant) {
        LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard";
        LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX";
    })(LanguageVariant = ts.LanguageVariant || (ts.LanguageVariant = {}));
    /* @internal */
    var DiagnosticStyle;
    (function (DiagnosticStyle) {
        DiagnosticStyle[DiagnosticStyle["Simple"] = 0] = "Simple";
        DiagnosticStyle[DiagnosticStyle["Pretty"] = 1] = "Pretty";
    })(DiagnosticStyle = ts.DiagnosticStyle || (ts.DiagnosticStyle = {}));
    var WatchDirectoryFlags;
    (function (WatchDirectoryFlags) {
        WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None";
        WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive";
    })(WatchDirectoryFlags = ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {}));
    /* @internal */
    var CharacterCodes;
    (function (CharacterCodes) {
        CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
        CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
        CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
        CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
        CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
        CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
        CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
        // Unicode 3.0 space characters
        CharacterCodes[CharacterCodes["space"] = 32] = "space";
        CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
        CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
        CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
        CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
        CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
        CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
        CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
        CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
        CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
        CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
        CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
        CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
        CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
        CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
        CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
        CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
        CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
        CharacterCodes[CharacterCodes["_"] = 95] = "_";
        CharacterCodes[CharacterCodes["$"] = 36] = "$";
        CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
        CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
        CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
        CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
        CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
        CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
        CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
        CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
        CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
        CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
        CharacterCodes[CharacterCodes["a"] = 97] = "a";
        CharacterCodes[CharacterCodes["b"] = 98] = "b";
        CharacterCodes[CharacterCodes["c"] = 99] = "c";
        CharacterCodes[CharacterCodes["d"] = 100] = "d";
        CharacterCodes[CharacterCodes["e"] = 101] = "e";
        CharacterCodes[CharacterCodes["f"] = 102] = "f";
        CharacterCodes[CharacterCodes["g"] = 103] = "g";
        CharacterCodes[CharacterCodes["h"] = 104] = "h";
        CharacterCodes[CharacterCodes["i"] = 105] = "i";
        CharacterCodes[CharacterCodes["j"] = 106] = "j";
        CharacterCodes[CharacterCodes["k"] = 107] = "k";
        CharacterCodes[CharacterCodes["l"] = 108] = "l";
        CharacterCodes[CharacterCodes["m"] = 109] = "m";
        CharacterCodes[CharacterCodes["n"] = 110] = "n";
        CharacterCodes[CharacterCodes["o"] = 111] = "o";
        CharacterCodes[CharacterCodes["p"] = 112] = "p";
        CharacterCodes[CharacterCodes["q"] = 113] = "q";
        CharacterCodes[CharacterCodes["r"] = 114] = "r";
        CharacterCodes[CharacterCodes["s"] = 115] = "s";
        CharacterCodes[CharacterCodes["t"] = 116] = "t";
        CharacterCodes[CharacterCodes["u"] = 117] = "u";
        CharacterCodes[CharacterCodes["v"] = 118] = "v";
        CharacterCodes[CharacterCodes["w"] = 119] = "w";
        CharacterCodes[CharacterCodes["x"] = 120] = "x";
        CharacterCodes[CharacterCodes["y"] = 121] = "y";
        CharacterCodes[CharacterCodes["z"] = 122] = "z";
        CharacterCodes[CharacterCodes["A"] = 65] = "A";
        CharacterCodes[CharacterCodes["B"] = 66] = "B";
        CharacterCodes[CharacterCodes["C"] = 67] = "C";
        CharacterCodes[CharacterCodes["D"] = 68] = "D";
        CharacterCodes[CharacterCodes["E"] = 69] = "E";
        CharacterCodes[CharacterCodes["F"] = 70] = "F";
        CharacterCodes[CharacterCodes["G"] = 71] = "G";
        CharacterCodes[CharacterCodes["H"] = 72] = "H";
        CharacterCodes[CharacterCodes["I"] = 73] = "I";
        CharacterCodes[CharacterCodes["J"] = 74] = "J";
        CharacterCodes[CharacterCodes["K"] = 75] = "K";
        CharacterCodes[CharacterCodes["L"] = 76] = "L";
        CharacterCodes[CharacterCodes["M"] = 77] = "M";
        CharacterCodes[CharacterCodes["N"] = 78] = "N";
        CharacterCodes[CharacterCodes["O"] = 79] = "O";
        CharacterCodes[CharacterCodes["P"] = 80] = "P";
        CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
        CharacterCodes[CharacterCodes["R"] = 82] = "R";
        CharacterCodes[CharacterCodes["S"] = 83] = "S";
        CharacterCodes[CharacterCodes["T"] = 84] = "T";
        CharacterCodes[CharacterCodes["U"] = 85] = "U";
        CharacterCodes[CharacterCodes["V"] = 86] = "V";
        CharacterCodes[CharacterCodes["W"] = 87] = "W";
        CharacterCodes[CharacterCodes["X"] = 88] = "X";
        CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
        CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
        CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
        CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
        CharacterCodes[CharacterCodes["at"] = 64] = "at";
        CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
        CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick";
        CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
        CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
        CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
        CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
        CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
        CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
        CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
        CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
        CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
        CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
        CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
        CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
        CharacterCodes[CharacterCodes["hash"] = 35] = "hash";
        CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
        CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
        CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
        CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
        CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
        CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
        CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
        CharacterCodes[CharacterCodes["question"] = 63] = "question";
        CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
        CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
        CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
        CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
        CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
        CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
        CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
        CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
        CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
    })(CharacterCodes = ts.CharacterCodes || (ts.CharacterCodes = {}));
    var Extension;
    (function (Extension) {
        Extension["Ts"] = ".ts";
        Extension["Tsx"] = ".tsx";
        Extension["Dts"] = ".d.ts";
        Extension["Js"] = ".js";
        Extension["Jsx"] = ".jsx";
        Extension["Json"] = ".json";
    })(Extension = ts.Extension || (ts.Extension = {}));
    /* @internal */
    var TransformFlags;
    (function (TransformFlags) {
        TransformFlags[TransformFlags["None"] = 0] = "None";
        // Facts
        // - Flags used to indicate that a node or subtree contains syntax that requires transformation.
        TransformFlags[TransformFlags["TypeScript"] = 1] = "TypeScript";
        TransformFlags[TransformFlags["ContainsTypeScript"] = 2] = "ContainsTypeScript";
        TransformFlags[TransformFlags["ContainsJsx"] = 4] = "ContainsJsx";
        TransformFlags[TransformFlags["ContainsESNext"] = 8] = "ContainsESNext";
        TransformFlags[TransformFlags["ContainsES2017"] = 16] = "ContainsES2017";
        TransformFlags[TransformFlags["ContainsES2016"] = 32] = "ContainsES2016";
        TransformFlags[TransformFlags["ES2015"] = 64] = "ES2015";
        TransformFlags[TransformFlags["ContainsES2015"] = 128] = "ContainsES2015";
        TransformFlags[TransformFlags["Generator"] = 256] = "Generator";
        TransformFlags[TransformFlags["ContainsGenerator"] = 512] = "ContainsGenerator";
        TransformFlags[TransformFlags["DestructuringAssignment"] = 1024] = "DestructuringAssignment";
        TransformFlags[TransformFlags["ContainsDestructuringAssignment"] = 2048] = "ContainsDestructuringAssignment";
        // Markers
        // - Flags used to indicate that a subtree contains a specific transformation.
        TransformFlags[TransformFlags["ContainsDecorators"] = 4096] = "ContainsDecorators";
        TransformFlags[TransformFlags["ContainsPropertyInitializer"] = 8192] = "ContainsPropertyInitializer";
        TransformFlags[TransformFlags["ContainsLexicalThis"] = 16384] = "ContainsLexicalThis";
        TransformFlags[TransformFlags["ContainsCapturedLexicalThis"] = 32768] = "ContainsCapturedLexicalThis";
        TransformFlags[TransformFlags["ContainsLexicalThisInComputedPropertyName"] = 65536] = "ContainsLexicalThisInComputedPropertyName";
        TransformFlags[TransformFlags["ContainsDefaultValueAssignments"] = 131072] = "ContainsDefaultValueAssignments";
        TransformFlags[TransformFlags["ContainsParameterPropertyAssignments"] = 262144] = "ContainsParameterPropertyAssignments";
        TransformFlags[TransformFlags["ContainsSpread"] = 524288] = "ContainsSpread";
        TransformFlags[TransformFlags["ContainsObjectSpread"] = 1048576] = "ContainsObjectSpread";
        TransformFlags[TransformFlags["ContainsRest"] = 524288] = "ContainsRest";
        TransformFlags[TransformFlags["ContainsObjectRest"] = 1048576] = "ContainsObjectRest";
        TransformFlags[TransformFlags["ContainsComputedPropertyName"] = 2097152] = "ContainsComputedPropertyName";
        TransformFlags[TransformFlags["ContainsBlockScopedBinding"] = 4194304] = "ContainsBlockScopedBinding";
        TransformFlags[TransformFlags["ContainsBindingPattern"] = 8388608] = "ContainsBindingPattern";
        TransformFlags[TransformFlags["ContainsYield"] = 16777216] = "ContainsYield";
        TransformFlags[TransformFlags["ContainsHoistedDeclarationOrCompletion"] = 33554432] = "ContainsHoistedDeclarationOrCompletion";
        TransformFlags[TransformFlags["ContainsDynamicImport"] = 67108864] = "ContainsDynamicImport";
        // Please leave this as 1 << 29.
        // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
        // It is a good reminder of how much room we have left
        TransformFlags[TransformFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        // Assertions
        // - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
        TransformFlags[TransformFlags["AssertTypeScript"] = 3] = "AssertTypeScript";
        TransformFlags[TransformFlags["AssertJsx"] = 4] = "AssertJsx";
        TransformFlags[TransformFlags["AssertESNext"] = 8] = "AssertESNext";
        TransformFlags[TransformFlags["AssertES2017"] = 16] = "AssertES2017";
        TransformFlags[TransformFlags["AssertES2016"] = 32] = "AssertES2016";
        TransformFlags[TransformFlags["AssertES2015"] = 192] = "AssertES2015";
        TransformFlags[TransformFlags["AssertGenerator"] = 768] = "AssertGenerator";
        TransformFlags[TransformFlags["AssertDestructuringAssignment"] = 3072] = "AssertDestructuringAssignment";
        // Scope Exclusions
        // - Bitmasks that exclude flags from propagating out of a specific context
        //   into the subtree flags of their container.
        TransformFlags[TransformFlags["NodeExcludes"] = 536872257] = "NodeExcludes";
        TransformFlags[TransformFlags["ArrowFunctionExcludes"] = 601249089] = "ArrowFunctionExcludes";
        TransformFlags[TransformFlags["FunctionExcludes"] = 601281857] = "FunctionExcludes";
        TransformFlags[TransformFlags["ConstructorExcludes"] = 601015617] = "ConstructorExcludes";
        TransformFlags[TransformFlags["MethodOrAccessorExcludes"] = 601015617] = "MethodOrAccessorExcludes";
        TransformFlags[TransformFlags["ClassExcludes"] = 539358529] = "ClassExcludes";
        TransformFlags[TransformFlags["ModuleExcludes"] = 574674241] = "ModuleExcludes";
        TransformFlags[TransformFlags["TypeExcludes"] = -3] = "TypeExcludes";
        TransformFlags[TransformFlags["ObjectLiteralExcludes"] = 540087617] = "ObjectLiteralExcludes";
        TransformFlags[TransformFlags["ArrayLiteralOrCallOrNewExcludes"] = 537396545] = "ArrayLiteralOrCallOrNewExcludes";
        TransformFlags[TransformFlags["VariableDeclarationListExcludes"] = 546309441] = "VariableDeclarationListExcludes";
        TransformFlags[TransformFlags["ParameterExcludes"] = 536872257] = "ParameterExcludes";
        TransformFlags[TransformFlags["CatchClauseExcludes"] = 537920833] = "CatchClauseExcludes";
        TransformFlags[TransformFlags["BindingPatternExcludes"] = 537396545] = "BindingPatternExcludes";
        // Masks
        // - Additional bitmasks
        TransformFlags[TransformFlags["TypeScriptClassSyntaxMask"] = 274432] = "TypeScriptClassSyntaxMask";
        TransformFlags[TransformFlags["ES2015FunctionSyntaxMask"] = 163840] = "ES2015FunctionSyntaxMask";
    })(TransformFlags = ts.TransformFlags || (ts.TransformFlags = {}));
    var EmitFlags;
    (function (EmitFlags) {
        EmitFlags[EmitFlags["SingleLine"] = 1] = "SingleLine";
        EmitFlags[EmitFlags["AdviseOnEmitNode"] = 2] = "AdviseOnEmitNode";
        EmitFlags[EmitFlags["NoSubstitution"] = 4] = "NoSubstitution";
        EmitFlags[EmitFlags["CapturesThis"] = 8] = "CapturesThis";
        EmitFlags[EmitFlags["NoLeadingSourceMap"] = 16] = "NoLeadingSourceMap";
        EmitFlags[EmitFlags["NoTrailingSourceMap"] = 32] = "NoTrailingSourceMap";
        EmitFlags[EmitFlags["NoSourceMap"] = 48] = "NoSourceMap";
        EmitFlags[EmitFlags["NoNestedSourceMaps"] = 64] = "NoNestedSourceMaps";
        EmitFlags[EmitFlags["NoTokenLeadingSourceMaps"] = 128] = "NoTokenLeadingSourceMaps";
        EmitFlags[EmitFlags["NoTokenTrailingSourceMaps"] = 256] = "NoTokenTrailingSourceMaps";
        EmitFlags[EmitFlags["NoTokenSourceMaps"] = 384] = "NoTokenSourceMaps";
        EmitFlags[EmitFlags["NoLeadingComments"] = 512] = "NoLeadingComments";
        EmitFlags[EmitFlags["NoTrailingComments"] = 1024] = "NoTrailingComments";
        EmitFlags[EmitFlags["NoComments"] = 1536] = "NoComments";
        EmitFlags[EmitFlags["NoNestedComments"] = 2048] = "NoNestedComments";
        EmitFlags[EmitFlags["HelperName"] = 4096] = "HelperName";
        EmitFlags[EmitFlags["ExportName"] = 8192] = "ExportName";
        EmitFlags[EmitFlags["LocalName"] = 16384] = "LocalName";
        EmitFlags[EmitFlags["InternalName"] = 32768] = "InternalName";
        EmitFlags[EmitFlags["Indented"] = 65536] = "Indented";
        EmitFlags[EmitFlags["NoIndentation"] = 131072] = "NoIndentation";
        EmitFlags[EmitFlags["AsyncFunctionBody"] = 262144] = "AsyncFunctionBody";
        EmitFlags[EmitFlags["ReuseTempVariableScope"] = 524288] = "ReuseTempVariableScope";
        EmitFlags[EmitFlags["CustomPrologue"] = 1048576] = "CustomPrologue";
        EmitFlags[EmitFlags["NoHoisting"] = 2097152] = "NoHoisting";
        EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
        EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
        EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
    })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
    /**
     * Used by the checker, this enum keeps track of external emit helpers that should be type
     * checked.
     */
    /* @internal */
    var ExternalEmitHelpers;
    (function (ExternalEmitHelpers) {
        ExternalEmitHelpers[ExternalEmitHelpers["Extends"] = 1] = "Extends";
        ExternalEmitHelpers[ExternalEmitHelpers["Assign"] = 2] = "Assign";
        ExternalEmitHelpers[ExternalEmitHelpers["Rest"] = 4] = "Rest";
        ExternalEmitHelpers[ExternalEmitHelpers["Decorate"] = 8] = "Decorate";
        ExternalEmitHelpers[ExternalEmitHelpers["Metadata"] = 16] = "Metadata";
        ExternalEmitHelpers[ExternalEmitHelpers["Param"] = 32] = "Param";
        ExternalEmitHelpers[ExternalEmitHelpers["Awaiter"] = 64] = "Awaiter";
        ExternalEmitHelpers[ExternalEmitHelpers["Generator"] = 128] = "Generator";
        ExternalEmitHelpers[ExternalEmitHelpers["Values"] = 256] = "Values";
        ExternalEmitHelpers[ExternalEmitHelpers["Read"] = 512] = "Read";
        ExternalEmitHelpers[ExternalEmitHelpers["Spread"] = 1024] = "Spread";
        ExternalEmitHelpers[ExternalEmitHelpers["Await"] = 2048] = "Await";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGenerator"] = 4096] = "AsyncGenerator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegator"] = 8192] = "AsyncDelegator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncValues"] = 16384] = "AsyncValues";
        ExternalEmitHelpers[ExternalEmitHelpers["ExportStar"] = 32768] = "ExportStar";
        ExternalEmitHelpers[ExternalEmitHelpers["MakeTemplateObject"] = 65536] = "MakeTemplateObject";
        ExternalEmitHelpers[ExternalEmitHelpers["FirstEmitHelper"] = 1] = "FirstEmitHelper";
        ExternalEmitHelpers[ExternalEmitHelpers["LastEmitHelper"] = 65536] = "LastEmitHelper";
        // Helpers included by ES2015 for..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForOfIncludes"] = 256] = "ForOfIncludes";
        // Helpers included by ES2017 for..await..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForAwaitOfIncludes"] = 16384] = "ForAwaitOfIncludes";
        // Helpers included by ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGeneratorIncludes"] = 6144] = "AsyncGeneratorIncludes";
        // Helpers included by yield* in ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegatorIncludes"] = 26624] = "AsyncDelegatorIncludes";
        // Helpers included by ES2015 spread
        ExternalEmitHelpers[ExternalEmitHelpers["SpreadIncludes"] = 1536] = "SpreadIncludes";
    })(ExternalEmitHelpers = ts.ExternalEmitHelpers || (ts.ExternalEmitHelpers = {}));
    var EmitHint;
    (function (EmitHint) {
        EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile";
        EmitHint[EmitHint["Expression"] = 1] = "Expression";
        EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName";
        EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter";
        EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified";
    })(EmitHint = ts.EmitHint || (ts.EmitHint = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /** Gets a timestamp with (at least) ms resolution */
    ts.timestamp = typeof performance !== "undefined" && performance.now ? function () { return performance.now(); } : Date.now ? Date.now : function () { return +(new Date()); };
})(ts || (ts = {}));
/*@internal*/
/** Performance measurements for the compiler. */
(function (ts) {
    var performance;
    (function (performance) {
        var profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
            ? onProfilerEvent
            : function (_markName) { };
        var enabled = false;
        var profilerStart = 0;
        var counts;
        var marks;
        var measures;
        /**
         * Marks a performance event.
         *
         * @param markName The name of the mark.
         */
        function mark(markName) {
            if (enabled) {
                marks.set(markName, ts.timestamp());
                counts.set(markName, (counts.get(markName) || 0) + 1);
                profilerEvent(markName);
            }
        }
        performance.mark = mark;
        /**
         * Adds a performance measurement with the specified name.
         *
         * @param measureName The name of the performance measurement.
         * @param startMarkName The name of the starting mark. If not supplied, the point at which the
         *      profiler was enabled is used.
         * @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
         *      used.
         */
        function measure(measureName, startMarkName, endMarkName) {
            if (enabled) {
                var end = endMarkName && marks.get(endMarkName) || ts.timestamp();
                var start = startMarkName && marks.get(startMarkName) || profilerStart;
                measures.set(measureName, (measures.get(measureName) || 0) + (end - start));
            }
        }
        performance.measure = measure;
        /**
         * Gets the number of times a marker was encountered.
         *
         * @param markName The name of the mark.
         */
        function getCount(markName) {
            return counts && counts.get(markName) || 0;
        }
        performance.getCount = getCount;
        /**
         * Gets the total duration of all measurements with the supplied name.
         *
         * @param measureName The name of the measure whose durations should be accumulated.
         */
        function getDuration(measureName) {
            return measures && measures.get(measureName) || 0;
        }
        performance.getDuration = getDuration;
        /**
         * Iterate over each measure, performing some action
         *
         * @param cb The action to perform for each measure
         */
        function forEachMeasure(cb) {
            measures.forEach(function (measure, key) {
                cb(key, measure);
            });
        }
        performance.forEachMeasure = forEachMeasure;
        /** Enables (and resets) performance measurements for the compiler. */
        function enable() {
            counts = ts.createMap();
            marks = ts.createMap();
            measures = ts.createMap();
            enabled = true;
            profilerStart = ts.timestamp();
        }
        performance.enable = enable;
        /** Disables performance measurements for the compiler. */
        function disable() {
            enabled = false;
        }
        performance.disable = disable;
    })(performance = ts.performance || (ts.performance = {}));
})(ts || (ts = {}));
/// <reference path="types.ts"/>
/// <reference path="performance.ts" />
var ts;
(function (ts) {
    // WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
    // If changing the text in this section, be sure to test `configureNightly` too.
    ts.versionMajorMinor = "2.6";
    /** The version of the TypeScript compiler release */
    ts.version = ts.versionMajorMinor + ".1";
})(ts || (ts = {}));
(function (ts) {
    function isExternalModuleNameRelative(moduleName) {
        // TypeScript 1.0 spec (April 2014): 11.2.1
        // An external module name is "relative" if the first term is "." or "..".
        // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
        return ts.pathIsRelative(moduleName) || ts.isRootedDiskPath(moduleName);
    }
    ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
    ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
    // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
    ts.localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
    /** Create a MapLike with good performance. */
    function createDictionaryObject() {
        var map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword
        // Using 'delete' on an object causes V8 to put the object in dictionary mode.
        // This disables creation of hidden classes, which are expensive when an object is
        // constantly changing shape.
        map.__ = undefined;
        delete map.__;
        return map;
    }
    /** Create a new map. If a template object is provided, the map will copy entries from it. */
    function createMap() {
        return new MapCtr();
    }
    ts.createMap = createMap;
    /** Create a new escaped identifier map. */
    function createUnderscoreEscapedMap() {
        return new MapCtr();
    }
    ts.createUnderscoreEscapedMap = createUnderscoreEscapedMap;
    function createSymbolTable(symbols) {
        var result = createMap();
        if (symbols) {
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                result.set(symbol.escapedName, symbol);
            }
        }
        return result;
    }
    ts.createSymbolTable = createSymbolTable;
    function createMapFromTemplate(template) {
        var map = new MapCtr();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in template) {
            if (hasOwnProperty.call(template, key)) {
                map.set(key, template[key]);
            }
        }
        return map;
    }
    ts.createMapFromTemplate = createMapFromTemplate;
    // Internet Explorer's Map doesn't support iteration, so don't use it.
    // tslint:disable-next-line:no-in-operator
    var MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
    // Keep the class inside a function so it doesn't get compiled if it's not used.
    function shimMap() {
        var MapIterator = /** @class */ (function () {
            function MapIterator(data, selector) {
                this.index = 0;
                this.data = data;
                this.selector = selector;
                this.keys = Object.keys(data);
            }
            MapIterator.prototype.next = function () {
                var index = this.index;
                if (index < this.keys.length) {
                    this.index++;
                    return { value: this.selector(this.data, this.keys[index]), done: false };
                }
                return { value: undefined, done: true };
            };
            return MapIterator;
        }());
        return /** @class */ (function () {
            function class_1() {
                this.data = createDictionaryObject();
                this.size = 0;
            }
            class_1.prototype.get = function (key) {
                return this.data[key];
            };
            class_1.prototype.set = function (key, value) {
                if (!this.has(key)) {
                    this.size++;
                }
                this.data[key] = value;
                return this;
            };
            class_1.prototype.has = function (key) {
                // tslint:disable-next-line:no-in-operator
                return key in this.data;
            };
            class_1.prototype.delete = function (key) {
                if (this.has(key)) {
                    this.size--;
                    delete this.data[key];
                    return true;
                }
                return false;
            };
            class_1.prototype.clear = function () {
                this.data = createDictionaryObject();
                this.size = 0;
            };
            class_1.prototype.keys = function () {
                return new MapIterator(this.data, function (_data, key) { return key; });
            };
            class_1.prototype.values = function () {
                return new MapIterator(this.data, function (data, key) { return data[key]; });
            };
            class_1.prototype.entries = function () {
                return new MapIterator(this.data, function (data, key) { return [key, data[key]]; });
            };
            class_1.prototype.forEach = function (action) {
                for (var key in this.data) {
                    action(this.data[key], key);
                }
            };
            return class_1;
        }());
    }
    function toPath(fileName, basePath, getCanonicalFileName) {
        var nonCanonicalizedPath = isRootedDiskPath(fileName)
            ? normalizePath(fileName)
            : getNormalizedAbsolutePath(fileName, basePath);
        return getCanonicalFileName(nonCanonicalizedPath);
    }
    ts.toPath = toPath;
    var Comparison;
    (function (Comparison) {
        Comparison[Comparison["LessThan"] = -1] = "LessThan";
        Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
        Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
    })(Comparison = ts.Comparison || (ts.Comparison = {}));
    function length(array) {
        return array ? array.length : 0;
    }
    ts.length = length;
    /**
     * Iterates through 'array' by index and performs the callback on each element of array until the callback
     * returns a truthy value, then returns that value.
     * If no such value is found, the callback is applied to each element of array and undefined is returned.
     */
    function forEach(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEach = forEach;
    /** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
    function firstDefined(array, callback) {
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result !== undefined) {
                return result;
            }
        }
        return undefined;
    }
    ts.firstDefined = firstDefined;
    function findAncestor(node, callback) {
        while (node) {
            var result = callback(node);
            if (result === "quit") {
                return undefined;
            }
            else if (result) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.findAncestor = findAncestor;
    function zipWith(arrayA, arrayB, callback) {
        var result = [];
        Debug.assert(arrayA.length === arrayB.length);
        for (var i = 0; i < arrayA.length; i++) {
            result.push(callback(arrayA[i], arrayB[i], i));
        }
        return result;
    }
    ts.zipWith = zipWith;
    function zipToMap(keys, values) {
        Debug.assert(keys.length === values.length);
        var map = createMap();
        for (var i = 0; i < keys.length; ++i) {
            map.set(keys[i], values[i]);
        }
        return map;
    }
    ts.zipToMap = zipToMap;
    /**
     * Iterates through `array` by index and performs the callback on each element of array until the callback
     * returns a falsey value, then returns false.
     * If no such value is found, the callback is applied to each element of array and `true` is returned.
     */
    function every(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (!callback(array[i], i)) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.every = every;
    function find(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.find = find;
    function findLast(array, predicate) {
        for (var i = array.length - 1; i >= 0; i--) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.findLast = findLast;
    /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
    function findIndex(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findIndex = findIndex;
    /**
     * Returns the first truthy result of `callback`, or else fails.
     * This is like `forEach`, but never returns undefined.
     */
    function findMap(array, callback) {
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result) {
                return result;
            }
        }
        Debug.fail();
    }
    ts.findMap = findMap;
    function contains(array, value) {
        if (array) {
            for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
                var v = array_1[_i];
                if (v === value) {
                    return true;
                }
            }
        }
        return false;
    }
    ts.contains = contains;
    function indexOf(array, value) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (array[i] === value) {
                    return i;
                }
            }
        }
        return -1;
    }
    ts.indexOf = indexOf;
    function indexOfAnyCharCode(text, charCodes, start) {
        for (var i = start || 0; i < text.length; i++) {
            if (contains(charCodes, text.charCodeAt(i))) {
                return i;
            }
        }
        return -1;
    }
    ts.indexOfAnyCharCode = indexOfAnyCharCode;
    function countWhere(array, predicate) {
        var count = 0;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (predicate(v, i)) {
                    count++;
                }
            }
        }
        return count;
    }
    ts.countWhere = countWhere;
    function filter(array, f) {
        if (array) {
            var len = array.length;
            var i = 0;
            while (i < len && f(array[i]))
                i++;
            if (i < len) {
                var result = array.slice(0, i);
                i++;
                while (i < len) {
                    var item = array[i];
                    if (f(item)) {
                        result.push(item);
                    }
                    i++;
                }
                return result;
            }
        }
        return array;
    }
    ts.filter = filter;
    function filterMutate(array, f) {
        var outIndex = 0;
        for (var i = 0; i < array.length; i++) {
            if (f(array[i], i, array)) {
                array[outIndex] = array[i];
                outIndex++;
            }
        }
        array.length = outIndex;
    }
    ts.filterMutate = filterMutate;
    function clear(array) {
        array.length = 0;
    }
    ts.clear = clear;
    function map(array, f) {
        var result;
        if (array) {
            result = [];
            for (var i = 0; i < array.length; i++) {
                result.push(f(array[i], i));
            }
        }
        return result;
    }
    ts.map = map;
    function sameMap(array, f) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (result) {
                    result.push(f(array[i], i));
                }
                else {
                    var item = array[i];
                    var mapped = f(item, i);
                    if (item !== mapped) {
                        result = array.slice(0, i);
                        result.push(mapped);
                    }
                }
            }
        }
        return result || array;
    }
    ts.sameMap = sameMap;
    /**
     * Flattens an array containing a mix of array or non-array elements.
     *
     * @param array The array to flatten.
     */
    function flatten(array) {
        var result;
        if (array) {
            result = [];
            for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
                var v = array_2[_i];
                if (v) {
                    if (isArray(v)) {
                        addRange(result, v);
                    }
                    else {
                        result.push(v);
                    }
                }
            }
        }
        return result;
    }
    ts.flatten = flatten;
    /**
     * Maps an array. If the mapped value is an array, it is spread into the result.
     *
     * @param array The array to map.
     * @param mapfn The callback used to map the result into one or more values.
     */
    function flatMap(array, mapfn) {
        var result;
        if (array) {
            result = [];
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        addRange(result, v);
                    }
                    else {
                        result.push(v);
                    }
                }
            }
        }
        return result;
    }
    ts.flatMap = flatMap;
    function flatMapIter(iter, mapfn) {
        var result = [];
        while (true) {
            var _a = iter.next(), value = _a.value, done = _a.done;
            if (done)
                break;
            var res = mapfn(value);
            if (res) {
                if (isArray(res)) {
                    result.push.apply(result, res);
                }
                else {
                    result.push(res);
                }
            }
        }
        return result;
    }
    ts.flatMapIter = flatMapIter;
    function sameFlatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = mapfn(item, i);
                if (result || item !== mapped || isArray(mapped)) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (isArray(mapped)) {
                        addRange(result, mapped);
                    }
                    else {
                        result.push(mapped);
                    }
                }
            }
        }
        return result || array;
    }
    ts.sameFlatMap = sameFlatMap;
    function mapDefined(array, mapFn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = mapFn(item, i);
                if (mapped !== undefined) {
                    result.push(mapped);
                }
            }
        }
        return result;
    }
    ts.mapDefined = mapDefined;
    function mapDefinedIter(iter, mapFn) {
        var result = [];
        while (true) {
            var _a = iter.next(), value = _a.value, done = _a.done;
            if (done)
                break;
            var res = mapFn(value);
            if (res !== undefined) {
                result.push(res);
            }
        }
        return result;
    }
    ts.mapDefinedIter = mapDefinedIter;
    /**
     * Computes the first matching span of elements and returns a tuple of the first span
     * and the remaining elements.
     */
    function span(array, f) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (!f(array[i], i)) {
                    return [array.slice(0, i), array.slice(i)];
                }
            }
            return [array.slice(0), []];
        }
        return undefined;
    }
    ts.span = span;
    /**
     * Maps contiguous spans of values with the same key.
     *
     * @param array The array to map.
     * @param keyfn A callback used to select the key for an element.
     * @param mapfn A callback used to map a contiguous chunk of values to a single value.
     */
    function spanMap(array, keyfn, mapfn) {
        var result;
        if (array) {
            result = [];
            var len = array.length;
            var previousKey = void 0;
            var key = void 0;
            var start = 0;
            var pos = 0;
            while (start < len) {
                while (pos < len) {
                    var value = array[pos];
                    key = keyfn(value, pos);
                    if (pos === 0) {
                        previousKey = key;
                    }
                    else if (key !== previousKey) {
                        break;
                    }
                    pos++;
                }
                if (start < pos) {
                    var v = mapfn(array.slice(start, pos), previousKey, start, pos);
                    if (v) {
                        result.push(v);
                    }
                    start = pos;
                }
                previousKey = key;
                pos++;
            }
        }
        return result;
    }
    ts.spanMap = spanMap;
    function mapEntries(map, f) {
        if (!map) {
            return undefined;
        }
        var result = createMap();
        map.forEach(function (value, key) {
            var _a = f(key, value), newKey = _a[0], newValue = _a[1];
            result.set(newKey, newValue);
        });
        return result;
    }
    ts.mapEntries = mapEntries;
    function some(array, predicate) {
        if (array) {
            if (predicate) {
                for (var _i = 0, array_3 = array; _i < array_3.length; _i++) {
                    var v = array_3[_i];
                    if (predicate(v)) {
                        return true;
                    }
                }
            }
            else {
                return array.length > 0;
            }
        }
        return false;
    }
    ts.some = some;
    function concatenate(array1, array2) {
        if (!some(array2))
            return array1;
        if (!some(array1))
            return array2;
        return array1.concat(array2);
    }
    ts.concatenate = concatenate;
    // TODO: fixme (N^2) - add optional comparer so collection can be sorted before deduplication.
    function deduplicate(array, areEqual) {
        var result;
        if (array) {
            result = [];
            loop: for (var _i = 0, array_4 = array; _i < array_4.length; _i++) {
                var item = array_4[_i];
                for (var _a = 0, result_1 = result; _a < result_1.length; _a++) {
                    var res = result_1[_a];
                    if (areEqual ? areEqual(res, item) : res === item) {
                        continue loop;
                    }
                }
                result.push(item);
            }
        }
        return result;
    }
    ts.deduplicate = deduplicate;
    function arrayIsEqualTo(array1, array2, equaler) {
        if (!array1 || !array2) {
            return array1 === array2;
        }
        if (array1.length !== array2.length) {
            return false;
        }
        for (var i = 0; i < array1.length; i++) {
            var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
            if (!equals) {
                return false;
            }
        }
        return true;
    }
    ts.arrayIsEqualTo = arrayIsEqualTo;
    function changesAffectModuleResolution(oldOptions, newOptions) {
        return !oldOptions ||
            (oldOptions.module !== newOptions.module) ||
            (oldOptions.moduleResolution !== newOptions.moduleResolution) ||
            (oldOptions.noResolve !== newOptions.noResolve) ||
            (oldOptions.target !== newOptions.target) ||
            (oldOptions.noLib !== newOptions.noLib) ||
            (oldOptions.jsx !== newOptions.jsx) ||
            (oldOptions.allowJs !== newOptions.allowJs) ||
            (oldOptions.rootDir !== newOptions.rootDir) ||
            (oldOptions.configFilePath !== newOptions.configFilePath) ||
            (oldOptions.baseUrl !== newOptions.baseUrl) ||
            (oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
            !arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
            !arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
            !arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
            !equalOwnProperties(oldOptions.paths, newOptions.paths);
    }
    ts.changesAffectModuleResolution = changesAffectModuleResolution;
    function compact(array) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (result || !v) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (v) {
                        result.push(v);
                    }
                }
            }
        }
        return result || array;
    }
    ts.compact = compact;
    /**
     * Gets the relative complement of `arrayA` with respect to `b`, returning the elements that
     * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
     * based on the provided comparer.
     */
    function relativeComplement(arrayA, arrayB, comparer, offsetA, offsetB) {
        if (comparer === void 0) { comparer = compareValues; }
        if (offsetA === void 0) { offsetA = 0; }
        if (offsetB === void 0) { offsetB = 0; }
        if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0)
            return arrayB;
        var result = [];
        outer: for (; offsetB < arrayB.length; offsetB++) {
            inner: for (; offsetA < arrayA.length; offsetA++) {
                switch (comparer(arrayB[offsetB], arrayA[offsetA])) {
                    case -1 /* LessThan */: break inner;
                    case 0 /* EqualTo */: continue outer;
                    case 1 /* GreaterThan */: continue inner;
                }
            }
            result.push(arrayB[offsetB]);
        }
        return result;
    }
    ts.relativeComplement = relativeComplement;
    function sum(array, prop) {
        var result = 0;
        for (var _i = 0, array_5 = array; _i < array_5.length; _i++) {
            var v = array_5[_i];
            // Note: we need the following type assertion because of GH #17069
            result += v[prop];
        }
        return result;
    }
    ts.sum = sum;
    /**
     * Appends a value to an array, returning the array.
     *
     * @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
     * is created if `value` was appended.
     * @param value The value to append to the array. If `value` is `undefined`, nothing is
     * appended.
     */
    function append(to, value) {
        if (value === undefined)
            return to;
        if (to === undefined)
            return [value];
        to.push(value);
        return to;
    }
    ts.append = append;
    /**
     * Gets the actual offset into an array for a relative offset. Negative offsets indicate a
     * position offset from the end of the array.
     */
    function toOffset(array, offset) {
        return offset < 0 ? array.length + offset : offset;
    }
    /**
     * Appends a range of value to an array, returning the array.
     *
     * @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
     * is created if `value` was appended.
     * @param from The values to append to the array. If `from` is `undefined`, nothing is
     * appended. If an element of `from` is `undefined`, that element is not appended.
     * @param start The offset in `from` at which to start copying values.
     * @param end The offset in `from` at which to stop copying values (non-inclusive).
     */
    function addRange(to, from, start, end) {
        if (from === undefined || from.length === 0)
            return to;
        if (to === undefined)
            return from.slice(start, end);
        start = start === undefined ? 0 : toOffset(from, start);
        end = end === undefined ? from.length : toOffset(from, end);
        for (var i = start; i < end && i < from.length; i++) {
            var v = from[i];
            if (v !== undefined) {
                to.push(from[i]);
            }
        }
        return to;
    }
    ts.addRange = addRange;
    /**
     * @return Whether the value was added.
     */
    function pushIfUnique(array, toAdd) {
        if (contains(array, toAdd)) {
            return false;
        }
        else {
            array.push(toAdd);
            return true;
        }
    }
    ts.pushIfUnique = pushIfUnique;
    /**
     * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
     */
    function appendIfUnique(array, toAdd) {
        if (array) {
            pushIfUnique(array, toAdd);
            return array;
        }
        else {
            return [toAdd];
        }
    }
    ts.appendIfUnique = appendIfUnique;
    /**
     * Stable sort of an array. Elements equal to each other maintain their relative position in the array.
     */
    function stableSort(array, comparer) {
        if (comparer === void 0) { comparer = compareValues; }
        return array
            .map(function (_, i) { return i; }) // create array of indices
            .sort(function (x, y) { return comparer(array[x], array[y]) || compareValues(x, y); }) // sort indices by value then position
            .map(function (i) { return array[i]; }); // get sorted array
    }
    ts.stableSort = stableSort;
    function rangeEquals(array1, array2, pos, end) {
        while (pos < end) {
            if (array1[pos] !== array2[pos]) {
                return false;
            }
            pos++;
        }
        return true;
    }
    ts.rangeEquals = rangeEquals;
    /**
     * Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
     * A negative offset indicates the element should be retrieved from the end of the array.
     */
    function elementAt(array, offset) {
        if (array) {
            offset = toOffset(array, offset);
            if (offset < array.length) {
                return array[offset];
            }
        }
        return undefined;
    }
    ts.elementAt = elementAt;
    /**
     * Returns the first element of an array if non-empty, `undefined` otherwise.
     */
    function firstOrUndefined(array) {
        return elementAt(array, 0);
    }
    ts.firstOrUndefined = firstOrUndefined;
    function first(array) {
        Debug.assert(array.length !== 0);
        return array[0];
    }
    ts.first = first;
    /**
     * Returns the last element of an array if non-empty, `undefined` otherwise.
     */
    function lastOrUndefined(array) {
        return elementAt(array, -1);
    }
    ts.lastOrUndefined = lastOrUndefined;
    function last(array) {
        Debug.assert(array.length !== 0);
        return array[array.length - 1];
    }
    ts.last = last;
    /**
     * Returns the only element of an array if it contains only one element, `undefined` otherwise.
     */
    function singleOrUndefined(array) {
        return array && array.length === 1
            ? array[0]
            : undefined;
    }
    ts.singleOrUndefined = singleOrUndefined;
    function singleOrMany(array) {
        return array && array.length === 1
            ? array[0]
            : array;
    }
    ts.singleOrMany = singleOrMany;
    function replaceElement(array, index, value) {
        var result = array.slice(0);
        result[index] = value;
        return result;
    }
    ts.replaceElement = replaceElement;
    /**
     * Performs a binary search, finding the index at which 'value' occurs in 'array'.
     * If no such index is found, returns the 2's-complement of first index at which
     * number[index] exceeds number.
     * @param array A sorted array whose first element must be no larger than number
     * @param number The value to be searched for in the array.
     */
    function binarySearch(array, value, comparer, offset) {
        if (!array || array.length === 0) {
            return -1;
        }
        var low = offset || 0;
        var high = array.length - 1;
        comparer = comparer !== undefined
            ? comparer
            : function (v1, v2) { return (v1 < v2 ? -1 : (v1 > v2 ? 1 : 0)); };
        while (low <= high) {
            var middle = low + ((high - low) >> 1);
            var midValue = array[middle];
            if (comparer(midValue, value) === 0) {
                return middle;
            }
            else if (comparer(midValue, value) > 0) {
                high = middle - 1;
            }
            else {
                low = middle + 1;
            }
        }
        return ~low;
    }
    ts.binarySearch = binarySearch;
    function reduceLeft(array, f, initial, start, count) {
        if (array && array.length > 0) {
            var size = array.length;
            if (size > 0) {
                var pos = start === undefined || start < 0 ? 0 : start;
                var end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count;
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos++;
                }
                else {
                    result = initial;
                }
                while (pos <= end) {
                    result = f(result, array[pos], pos);
                    pos++;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceLeft = reduceLeft;
    function reduceRight(array, f, initial, start, count) {
        if (array) {
            var size = array.length;
            if (size > 0) {
                var pos = start === undefined || start > size - 1 ? size - 1 : start;
                var end = count === undefined || pos - count < 0 ? 0 : pos - count;
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos--;
                }
                else {
                    result = initial;
                }
                while (pos >= end) {
                    result = f(result, array[pos], pos);
                    pos--;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceRight = reduceRight;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    /**
     * Indicates whether a map-like contains an own property with the specified key.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function hasProperty(map, key) {
        return hasOwnProperty.call(map, key);
    }
    ts.hasProperty = hasProperty;
    /**
     * Gets the value of an owned property in a map-like.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function getProperty(map, key) {
        return hasOwnProperty.call(map, key) ? map[key] : undefined;
    }
    ts.getProperty = getProperty;
    /**
     * Gets the owned, enumerable property keys of a map-like.
     */
    function getOwnKeys(map) {
        var keys = [];
        for (var key in map) {
            if (hasOwnProperty.call(map, key)) {
                keys.push(key);
            }
        }
        return keys;
    }
    ts.getOwnKeys = getOwnKeys;
    function getOwnValues(sparseArray) {
        var values = [];
        for (var key in sparseArray) {
            if (hasOwnProperty.call(sparseArray, key)) {
                values.push(sparseArray[key]);
            }
        }
        return values;
    }
    ts.getOwnValues = getOwnValues;
    function arrayFrom(iterator, map) {
        var result = [];
        for (var _a = iterator.next(), value = _a.value, done = _a.done; !done; _b = iterator.next(), value = _b.value, done = _b.done, _b) {
            result.push(map ? map(value) : value);
        }
        return result;
        var _b;
    }
    ts.arrayFrom = arrayFrom;
    function forEachEntry(map, callback) {
        var iterator = map.entries();
        for (var _a = iterator.next(), pair = _a.value, done = _a.done; !done; _b = iterator.next(), pair = _b.value, done = _b.done, _b) {
            var key = pair[0], value = pair[1];
            var result = callback(value, key);
            if (result) {
                return result;
            }
        }
        return undefined;
        var _b;
    }
    ts.forEachEntry = forEachEntry;
    function forEachKey(map, callback) {
        var iterator = map.keys();
        for (var _a = iterator.next(), key = _a.value, done = _a.done; !done; _b = iterator.next(), key = _b.value, done = _b.done, _b) {
            var result = callback(key);
            if (result) {
                return result;
            }
        }
        return undefined;
        var _b;
    }
    ts.forEachKey = forEachKey;
    function copyEntries(source, target) {
        source.forEach(function (value, key) {
            target.set(key, value);
        });
    }
    ts.copyEntries = copyEntries;
    function assign(t) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
            var arg = args_1[_a];
            for (var p in arg) {
                if (hasProperty(arg, p)) {
                    t[p] = arg[p];
                }
            }
        }
        return t;
    }
    ts.assign = assign;
    /**
     * Performs a shallow equality comparison of the contents of two map-likes.
     *
     * @param left A map-like whose properties should be compared.
     * @param right A map-like whose properties should be compared.
     */
    function equalOwnProperties(left, right, equalityComparer) {
        if (left === right)
            return true;
        if (!left || !right)
            return false;
        for (var key in left) {
            if (hasOwnProperty.call(left, key)) {
                if (!hasOwnProperty.call(right, key) === undefined)
                    return false;
                if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key])
                    return false;
            }
        }
        for (var key in right) {
            if (hasOwnProperty.call(right, key)) {
                if (!hasOwnProperty.call(left, key))
                    return false;
            }
        }
        return true;
    }
    ts.equalOwnProperties = equalOwnProperties;
    function arrayToMap(array, makeKey, makeValue) {
        var result = createMap();
        for (var _i = 0, array_6 = array; _i < array_6.length; _i++) {
            var value = array_6[_i];
            result.set(makeKey(value), makeValue ? makeValue(value) : value);
        }
        return result;
    }
    ts.arrayToMap = arrayToMap;
    function arrayToNumericMap(array, makeKey) {
        var result = [];
        for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
            var value = array_7[_i];
            result[makeKey(value)] = value;
        }
        return result;
    }
    ts.arrayToNumericMap = arrayToNumericMap;
    function arrayToSet(array, makeKey) {
        return arrayToMap(array, makeKey || (function (s) { return s; }), function () { return true; });
    }
    ts.arrayToSet = arrayToSet;
    function cloneMap(map) {
        var clone = createMap();
        copyEntries(map, clone);
        return clone;
    }
    ts.cloneMap = cloneMap;
    function clone(object) {
        var result = {};
        for (var id in object) {
            if (hasOwnProperty.call(object, id)) {
                result[id] = object[id];
            }
        }
        return result;
    }
    ts.clone = clone;
    function extend(first, second) {
        var result = {};
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                result[id] = second[id];
            }
        }
        for (var id in first) {
            if (hasOwnProperty.call(first, id)) {
                result[id] = first[id];
            }
        }
        return result;
    }
    ts.extend = extend;
    function createMultiMap() {
        var map = createMap();
        map.add = multiMapAdd;
        map.remove = multiMapRemove;
        return map;
    }
    ts.createMultiMap = createMultiMap;
    function multiMapAdd(key, value) {
        var values = this.get(key);
        if (values) {
            values.push(value);
        }
        else {
            this.set(key, values = [value]);
        }
        return values;
    }
    function multiMapRemove(key, value) {
        var values = this.get(key);
        if (values) {
            unorderedRemoveItem(values, value);
            if (!values.length) {
                this.delete(key);
            }
        }
    }
    /**
     * Tests whether a value is an array.
     */
    function isArray(value) {
        return Array.isArray ? Array.isArray(value) : value instanceof Array;
    }
    ts.isArray = isArray;
    /**
     * Tests whether a value is string
     */
    function isString(text) {
        return typeof text === "string";
    }
    ts.isString = isString;
    function tryCast(value, test) {
        return value !== undefined && test(value) ? value : undefined;
    }
    ts.tryCast = tryCast;
    function cast(value, test) {
        if (value !== undefined && test(value))
            return value;
        Debug.fail("Invalid cast. The supplied value did not pass the test '" + Debug.getFunctionName(test) + "'.");
    }
    ts.cast = cast;
    /** Does nothing. */
    function noop() { }
    ts.noop = noop;
    /** Do nothing and return false */
    function returnFalse() { return false; }
    ts.returnFalse = returnFalse;
    /** Do nothing and return true */
    function returnTrue() { return true; }
    ts.returnTrue = returnTrue;
    /** Returns its argument. */
    function identity(x) { return x; }
    ts.identity = identity;
    /** Throws an error because a function is not implemented. */
    function notImplemented() {
        throw new Error("Not implemented");
    }
    ts.notImplemented = notImplemented;
    function memoize(callback) {
        var value;
        return function () {
            if (callback) {
                value = callback();
                callback = undefined;
            }
            return value;
        };
    }
    ts.memoize = memoize;
    function chain(a, b, c, d, e) {
        if (e) {
            var args_2 = [];
            for (var i = 0; i < arguments.length; i++) {
                args_2[i] = arguments[i];
            }
            return function (t) { return compose.apply(void 0, map(args_2, function (f) { return f(t); })); };
        }
        else if (d) {
            return function (t) { return compose(a(t), b(t), c(t), d(t)); };
        }
        else if (c) {
            return function (t) { return compose(a(t), b(t), c(t)); };
        }
        else if (b) {
            return function (t) { return compose(a(t), b(t)); };
        }
        else if (a) {
            return function (t) { return compose(a(t)); };
        }
        else {
            return function (_) { return function (u) { return u; }; };
        }
    }
    ts.chain = chain;
    function compose(a, b, c, d, e) {
        if (e) {
            var args_3 = [];
            for (var i = 0; i < arguments.length; i++) {
                args_3[i] = arguments[i];
            }
            return function (t) { return reduceLeft(args_3, function (u, f) { return f(u); }, t); };
        }
        else if (d) {
            return function (t) { return d(c(b(a(t)))); };
        }
        else if (c) {
            return function (t) { return c(b(a(t))); };
        }
        else if (b) {
            return function (t) { return b(a(t)); };
        }
        else if (a) {
            return function (t) { return a(t); };
        }
        else {
            return function (t) { return t; };
        }
    }
    ts.compose = compose;
    function formatStringFromArgs(text, args, baseIndex) {
        baseIndex = baseIndex || 0;
        return text.replace(/{(\d+)}/g, function (_match, index) { return args[+index + baseIndex]; });
    }
    ts.formatStringFromArgs = formatStringFromArgs;
    ts.localizedDiagnosticMessages = undefined;
    function getLocaleSpecificMessage(message) {
        return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key] || message.message;
    }
    ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
    function createFileDiagnostic(file, start, length, message) {
        Debug.assertGreaterThanOrEqual(start, 0);
        Debug.assertGreaterThanOrEqual(length, 0);
        if (file) {
            Debug.assertLessThanOrEqual(start, file.text.length);
            Debug.assertLessThanOrEqual(start + length, file.text.length);
        }
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 4) {
            text = formatStringFromArgs(text, arguments, 4);
        }
        return {
            file: file,
            start: start,
            length: length,
            messageText: text,
            category: message.category,
            code: message.code,
        };
    }
    ts.createFileDiagnostic = createFileDiagnostic;
    /* internal */
    function formatMessage(_dummy, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return text;
    }
    ts.formatMessage = formatMessage;
    function createCompilerDiagnostic(message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 1) {
            text = formatStringFromArgs(text, arguments, 1);
        }
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            messageText: text,
            category: message.category,
            code: message.code
        };
    }
    ts.createCompilerDiagnostic = createCompilerDiagnostic;
    function createCompilerDiagnosticFromMessageChain(chain) {
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            code: chain.code,
            category: chain.category,
            messageText: chain.next ? chain : chain.messageText
        };
    }
    ts.createCompilerDiagnosticFromMessageChain = createCompilerDiagnosticFromMessageChain;
    function chainDiagnosticMessages(details, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return {
            messageText: text,
            category: message.category,
            code: message.code,
            next: details
        };
    }
    ts.chainDiagnosticMessages = chainDiagnosticMessages;
    function concatenateDiagnosticMessageChains(headChain, tailChain) {
        var lastChain = headChain;
        while (lastChain.next) {
            lastChain = lastChain.next;
        }
        lastChain.next = tailChain;
        return headChain;
    }
    ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains;
    function compareValues(a, b) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        return a < b ? -1 /* LessThan */ : 1 /* GreaterThan */;
    }
    ts.compareValues = compareValues;
    function compareStrings(a, b, ignoreCase) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        if (ignoreCase) {
            // Checking if "collator exists indicates that Intl is available.
            // We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre"
            if (ts.collator) {
                var result = ts.localeCompareIsCorrect ?
                    ts.collator.compare(a, b) :
                    a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A
                return result < 0 ? -1 /* LessThan */ : result > 0 ? 1 /* GreaterThan */ : 0 /* EqualTo */;
            }
            a = a.toUpperCase();
            b = b.toUpperCase();
            if (a === b)
                return 0 /* EqualTo */;
        }
        return a < b ? -1 /* LessThan */ : 1 /* GreaterThan */;
    }
    ts.compareStrings = compareStrings;
    function compareStringsCaseInsensitive(a, b) {
        return compareStrings(a, b, /*ignoreCase*/ true);
    }
    ts.compareStringsCaseInsensitive = compareStringsCaseInsensitive;
    function getDiagnosticFileName(diagnostic) {
        return diagnostic.file ? diagnostic.file.fileName : undefined;
    }
    function compareDiagnostics(d1, d2) {
        return compareValues(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) ||
            compareValues(d1.start, d2.start) ||
            compareValues(d1.length, d2.length) ||
            compareValues(d1.code, d2.code) ||
            compareMessageText(d1.messageText, d2.messageText) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnostics = compareDiagnostics;
    function compareMessageText(text1, text2) {
        while (text1 && text2) {
            // We still have both chains.
            var string1 = isString(text1) ? text1 : text1.messageText;
            var string2 = isString(text2) ? text2 : text2.messageText;
            var res = compareValues(string1, string2);
            if (res) {
                return res;
            }
            text1 = isString(text1) ? undefined : text1.next;
            text2 = isString(text2) ? undefined : text2.next;
        }
        if (!text1 && !text2) {
            // if the chains are done, then these messages are the same.
            return 0 /* EqualTo */;
        }
        // We still have one chain remaining.  The shorter chain should come first.
        return text1 ? 1 /* GreaterThan */ : -1 /* LessThan */;
    }
    function sortAndDeduplicateDiagnostics(diagnostics) {
        return deduplicateSortedDiagnostics(diagnostics.sort(compareDiagnostics));
    }
    ts.sortAndDeduplicateDiagnostics = sortAndDeduplicateDiagnostics;
    function deduplicateSortedDiagnostics(diagnostics) {
        if (diagnostics.length < 2) {
            return diagnostics;
        }
        var newDiagnostics = [diagnostics[0]];
        var previousDiagnostic = diagnostics[0];
        for (var i = 1; i < diagnostics.length; i++) {
            var currentDiagnostic = diagnostics[i];
            var isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === 0 /* EqualTo */;
            if (!isDupe) {
                newDiagnostics.push(currentDiagnostic);
                previousDiagnostic = currentDiagnostic;
            }
        }
        return newDiagnostics;
    }
    ts.deduplicateSortedDiagnostics = deduplicateSortedDiagnostics;
    function normalizeSlashes(path) {
        return path.replace(/\\/g, "/");
    }
    ts.normalizeSlashes = normalizeSlashes;
    /**
     * Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
     */
    function getRootLength(path) {
        if (path.charCodeAt(0) === 47 /* slash */) {
            if (path.charCodeAt(1) !== 47 /* slash */)
                return 1;
            var p1 = path.indexOf("/", 2);
            if (p1 < 0)
                return 2;
            var p2 = path.indexOf("/", p1 + 1);
            if (p2 < 0)
                return p1 + 1;
            return p2 + 1;
        }
        if (path.charCodeAt(1) === 58 /* colon */) {
            if (path.charCodeAt(2) === 47 /* slash */)
                return 3;
            return 2;
        }
        // Per RFC 1738 'file' URI schema has the shape file://<host>/<path>
        // if <host> is omitted then it is assumed that host value is 'localhost',
        // however slash after the omitted <host> is not removed.
        // file:///folder1/file1 - this is a correct URI
        // file://folder2/file2 - this is an incorrect URI
        if (path.lastIndexOf("file:///", 0) === 0) {
            return "file:///".length;
        }
        var idx = path.indexOf("://");
        if (idx !== -1) {
            return idx + "://".length;
        }
        return 0;
    }
    ts.getRootLength = getRootLength;
    /**
     * Internally, we represent paths as strings with '/' as the directory separator.
     * When we make system calls (eg: LanguageServiceHost.getDirectory()),
     * we expect the host to correctly handle paths in our specified format.
     */
    ts.directorySeparator = "/";
    var directorySeparatorCharCode = 47 /* slash */;
    function getNormalizedParts(normalizedSlashedPath, rootLength) {
        var parts = normalizedSlashedPath.substr(rootLength).split(ts.directorySeparator);
        var normalized = [];
        for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
            var part = parts_1[_i];
            if (part !== ".") {
                if (part === ".." && normalized.length > 0 && lastOrUndefined(normalized) !== "..") {
                    normalized.pop();
                }
                else {
                    // A part may be an empty string (which is 'falsy') if the path had consecutive slashes,
                    // e.g. "path//file.ts".  Drop these before re-joining the parts.
                    if (part) {
                        normalized.push(part);
                    }
                }
            }
        }
        return normalized;
    }
    function normalizePath(path) {
        return normalizePathAndParts(path).path;
    }
    ts.normalizePath = normalizePath;
    function normalizePathAndParts(path) {
        path = normalizeSlashes(path);
        var rootLength = getRootLength(path);
        var root = path.substr(0, rootLength);
        var parts = getNormalizedParts(path, rootLength);
        if (parts.length) {
            var joinedParts = root + parts.join(ts.directorySeparator);
            return { path: pathEndsWithDirectorySeparator(path) ? joinedParts + ts.directorySeparator : joinedParts, parts: parts };
        }
        else {
            return { path: root, parts: parts };
        }
    }
    ts.normalizePathAndParts = normalizePathAndParts;
    /** A path ending with '/' refers to a directory only, never a file. */
    function pathEndsWithDirectorySeparator(path) {
        return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
    }
    ts.pathEndsWithDirectorySeparator = pathEndsWithDirectorySeparator;
    function getDirectoryPath(path) {
        return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(ts.directorySeparator)));
    }
    ts.getDirectoryPath = getDirectoryPath;
    function isUrl(path) {
        return path && !isRootedDiskPath(path) && stringContains(path, "://");
    }
    ts.isUrl = isUrl;
    function pathIsRelative(path) {
        return /^\.\.?($|[\\/])/.test(path);
    }
    ts.pathIsRelative = pathIsRelative;
    /** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */
    function moduleHasNonRelativeName(moduleName) {
        return !ts.isExternalModuleNameRelative(moduleName);
    }
    ts.moduleHasNonRelativeName = moduleHasNonRelativeName;
    function getEmitScriptTarget(compilerOptions) {
        return compilerOptions.target || 0 /* ES3 */;
    }
    ts.getEmitScriptTarget = getEmitScriptTarget;
    function getEmitModuleKind(compilerOptions) {
        return typeof compilerOptions.module === "number" ?
            compilerOptions.module :
            getEmitScriptTarget(compilerOptions) >= 2 /* ES2015 */ ? ts.ModuleKind.ES2015 : ts.ModuleKind.CommonJS;
    }
    ts.getEmitModuleKind = getEmitModuleKind;
    function getEmitModuleResolutionKind(compilerOptions) {
        var moduleResolution = compilerOptions.moduleResolution;
        if (moduleResolution === undefined) {
            moduleResolution = getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
        }
        return moduleResolution;
    }
    ts.getEmitModuleResolutionKind = getEmitModuleResolutionKind;
    function hasZeroOrOneAsteriskCharacter(str) {
        var seenAsterisk = false;
        for (var i = 0; i < str.length; i++) {
            if (str.charCodeAt(i) === 42 /* asterisk */) {
                if (!seenAsterisk) {
                    seenAsterisk = true;
                }
                else {
                    // have already seen asterisk
                    return false;
                }
            }
        }
        return true;
    }
    ts.hasZeroOrOneAsteriskCharacter = hasZeroOrOneAsteriskCharacter;
    function isRootedDiskPath(path) {
        return path && getRootLength(path) !== 0;
    }
    ts.isRootedDiskPath = isRootedDiskPath;
    function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
        return !isRootedDiskPath(absoluteOrRelativePath)
            ? absoluteOrRelativePath
            : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
    }
    ts.convertToRelativePath = convertToRelativePath;
    function normalizedPathComponents(path, rootLength) {
        var normalizedParts = getNormalizedParts(path, rootLength);
        return [path.substr(0, rootLength)].concat(normalizedParts);
    }
    function getNormalizedPathComponents(path, currentDirectory) {
        path = normalizeSlashes(path);
        var rootLength = getRootLength(path);
        if (rootLength === 0) {
            // If the path is not rooted it is relative to current directory
            path = combinePaths(normalizeSlashes(currentDirectory), path);
            rootLength = getRootLength(path);
        }
        return normalizedPathComponents(path, rootLength);
    }
    ts.getNormalizedPathComponents = getNormalizedPathComponents;
    function getNormalizedAbsolutePath(fileName, currentDirectory) {
        return getNormalizedPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath;
    function getNormalizedPathFromPathComponents(pathComponents) {
        if (pathComponents && pathComponents.length) {
            return pathComponents[0] + pathComponents.slice(1).join(ts.directorySeparator);
        }
    }
    ts.getNormalizedPathFromPathComponents = getNormalizedPathFromPathComponents;
    function getNormalizedPathComponentsOfUrl(url) {
        // Get root length of http://www.website.com/folder1/folder2/
        // In this example the root is:  http://www.website.com/
        // normalized path components should be ["http://www.website.com/", "folder1", "folder2"]
        var urlLength = url.length;
        // Initial root length is http:// part
        var rootLength = url.indexOf("://") + "://".length;
        while (rootLength < urlLength) {
            // Consume all immediate slashes in the protocol
            // eg.initial rootlength is just file:// but it needs to consume another "/" in file:///
            if (url.charCodeAt(rootLength) === 47 /* slash */) {
                rootLength++;
            }
            else {
                // non slash character means we continue proceeding to next component of root search
                break;
            }
        }
        // there are no parts after http:// just return current string as the pathComponent
        if (rootLength === urlLength) {
            return [url];
        }
        // Find the index of "/" after website.com so the root can be http://www.website.com/ (from existing http://)
        var indexOfNextSlash = url.indexOf(ts.directorySeparator, rootLength);
        if (indexOfNextSlash !== -1) {
            // Found the "/" after the website.com so the root is length of http://www.website.com/
            // and get components after the root normally like any other folder components
            rootLength = indexOfNextSlash + 1;
            return normalizedPathComponents(url, rootLength);
        }
        else {
            // Can't find the host assume the rest of the string as component
            // but make sure we append "/"  to it as root is not joined using "/"
            // eg. if url passed in was http://website.com we want to use root as [http://website.com/]
            // so that other path manipulations will be correct and it can be merged with relative paths correctly
            return [url + ts.directorySeparator];
        }
    }
    function getNormalizedPathOrUrlComponents(pathOrUrl, currentDirectory) {
        if (isUrl(pathOrUrl)) {
            return getNormalizedPathComponentsOfUrl(pathOrUrl);
        }
        else {
            return getNormalizedPathComponents(pathOrUrl, currentDirectory);
        }
    }
    function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) {
        var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory);
        var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
        if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") {
            // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name
            // that is  ["test", "cases", ""] needs to be actually ["test", "cases"]
            directoryComponents.pop();
        }
        // Find the component that differs
        var joinStartIndex;
        for (joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) {
            if (getCanonicalFileName(directoryComponents[joinStartIndex]) !== getCanonicalFileName(pathComponents[joinStartIndex])) {
                break;
            }
        }
        // Get the relative path
        if (joinStartIndex) {
            var relativePath = "";
            var relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length);
            for (; joinStartIndex < directoryComponents.length; joinStartIndex++) {
                if (directoryComponents[joinStartIndex] !== "") {
                    relativePath = relativePath + ".." + ts.directorySeparator;
                }
            }
            return relativePath + relativePathComponents.join(ts.directorySeparator);
        }
        // Cant find the relative path, get the absolute path
        var absolutePath = getNormalizedPathFromPathComponents(pathComponents);
        if (isAbsolutePathAnUrl && isRootedDiskPath(absolutePath)) {
            absolutePath = "file:///" + absolutePath;
        }
        return absolutePath;
    }
    ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl;
    function getBaseFileName(path) {
        if (path === undefined) {
            return undefined;
        }
        var i = path.lastIndexOf(ts.directorySeparator);
        return i < 0 ? path : path.substring(i + 1);
    }
    ts.getBaseFileName = getBaseFileName;
    function combinePaths(path1, path2) {
        if (!(path1 && path1.length))
            return path2;
        if (!(path2 && path2.length))
            return path1;
        if (getRootLength(path2) !== 0)
            return path2;
        if (path1.charAt(path1.length - 1) === ts.directorySeparator)
            return path1 + path2;
        return path1 + ts.directorySeparator + path2;
    }
    ts.combinePaths = combinePaths;
    function removeTrailingDirectorySeparator(path) {
        if (path.charAt(path.length - 1) === ts.directorySeparator) {
            return path.substr(0, path.length - 1);
        }
        return path;
    }
    ts.removeTrailingDirectorySeparator = removeTrailingDirectorySeparator;
    /**
     * Adds a trailing directory separator to a path, if it does not already have one.
     * @param path The path.
     */
    function ensureTrailingDirectorySeparator(path) {
        if (path.charAt(path.length - 1) !== ts.directorySeparator) {
            return path + ts.directorySeparator;
        }
        return path;
    }
    ts.ensureTrailingDirectorySeparator = ensureTrailingDirectorySeparator;
    function comparePaths(a, b, currentDirectory, ignoreCase) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        a = removeTrailingDirectorySeparator(a);
        b = removeTrailingDirectorySeparator(b);
        var aComponents = getNormalizedPathComponents(a, currentDirectory);
        var bComponents = getNormalizedPathComponents(b, currentDirectory);
        var sharedLength = Math.min(aComponents.length, bComponents.length);
        for (var i = 0; i < sharedLength; i++) {
            var result = compareStrings(aComponents[i], bComponents[i], ignoreCase);
            if (result !== 0 /* EqualTo */) {
                return result;
            }
        }
        return compareValues(aComponents.length, bComponents.length);
    }
    ts.comparePaths = comparePaths;
    function containsPath(parent, child, currentDirectory, ignoreCase) {
        if (parent === undefined || child === undefined)
            return false;
        if (parent === child)
            return true;
        parent = removeTrailingDirectorySeparator(parent);
        child = removeTrailingDirectorySeparator(child);
        if (parent === child)
            return true;
        var parentComponents = getNormalizedPathComponents(parent, currentDirectory);
        var childComponents = getNormalizedPathComponents(child, currentDirectory);
        if (childComponents.length < parentComponents.length) {
            return false;
        }
        for (var i = 0; i < parentComponents.length; i++) {
            var result = compareStrings(parentComponents[i], childComponents[i], ignoreCase);
            if (result !== 0 /* EqualTo */) {
                return false;
            }
        }
        return true;
    }
    ts.containsPath = containsPath;
    function startsWith(str, prefix) {
        return str.lastIndexOf(prefix, 0) === 0;
    }
    ts.startsWith = startsWith;
    function removePrefix(str, prefix) {
        return startsWith(str, prefix) ? str.substr(prefix.length) : str;
    }
    ts.removePrefix = removePrefix;
    function endsWith(str, suffix) {
        var expectedPos = str.length - suffix.length;
        return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
    }
    ts.endsWith = endsWith;
    function stringContains(str, substring) {
        return str.indexOf(substring) !== -1;
    }
    ts.stringContains = stringContains;
    function hasExtension(fileName) {
        return stringContains(getBaseFileName(fileName), ".");
    }
    ts.hasExtension = hasExtension;
    function fileExtensionIs(path, extension) {
        return path.length > extension.length && endsWith(path, extension);
    }
    ts.fileExtensionIs = fileExtensionIs;
    function fileExtensionIsOneOf(path, extensions) {
        for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
            var extension = extensions_1[_i];
            if (fileExtensionIs(path, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.fileExtensionIsOneOf = fileExtensionIsOneOf;
    // Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
    // It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
    // proof.
    var reservedCharacterPattern = /[^\w\s\/]/g;
    var wildcardCharCodes = [42 /* asterisk */, 63 /* question */];
    ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"];
    var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))";
    var filesMatcher = {
        /**
         * Matches any single directory segment unless it is the last segment and a .min.js file
         * Breakdown:
         *  [^./]                   # matches everything up to the first . character (excluding directory seperators)
         *  (\\.(?!min\\.js$))?     # matches . characters but not if they are part of the .min.js file extension
         */
        singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); }
    };
    var directoriesMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); }
    };
    var excludeMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        doubleAsteriskRegexFragment: "(/.+?)?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); }
    };
    var wildcardMatchers = {
        files: filesMatcher,
        directories: directoriesMatcher,
        exclude: excludeMatcher
    };
    function getRegularExpressionForWildcard(specs, basePath, usage) {
        var patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
        if (!patterns || !patterns.length) {
            return undefined;
        }
        var pattern = patterns.map(function (pattern) { return "(" + pattern + ")"; }).join("|");
        // If excluding, match "foo/bar/baz...", but if including, only allow "foo".
        var terminator = usage === "exclude" ? "($|/)" : "$";
        return "^(" + pattern + ")" + terminator;
    }
    ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard;
    function getRegularExpressionsForWildcards(specs, basePath, usage) {
        if (specs === undefined || specs.length === 0) {
            return undefined;
        }
        return flatMap(specs, function (spec) {
            return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
        });
    }
    /**
     * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
     * and does not contain any glob characters itself.
     */
    function isImplicitGlob(lastPathComponent) {
        return !/[.*?]/.test(lastPathComponent);
    }
    ts.isImplicitGlob = isImplicitGlob;
    function getSubPatternFromSpec(spec, basePath, usage, _a) {
        var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter;
        var subpattern = "";
        var hasRecursiveDirectoryWildcard = false;
        var hasWrittenComponent = false;
        var components = getNormalizedPathComponents(spec, basePath);
        var lastComponent = lastOrUndefined(components);
        if (usage !== "exclude" && lastComponent === "**") {
            return undefined;
        }
        // getNormalizedPathComponents includes the separator for the root component.
        // We need to remove to create our regex correctly.
        components[0] = removeTrailingDirectorySeparator(components[0]);
        if (isImplicitGlob(lastComponent)) {
            components.push("**", "*");
        }
        var optionalCount = 0;
        for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
            var component = components_1[_i];
            if (component === "**") {
                if (hasRecursiveDirectoryWildcard) {
                    return undefined;
                }
                subpattern += doubleAsteriskRegexFragment;
                hasRecursiveDirectoryWildcard = true;
            }
            else {
                if (usage === "directories") {
                    subpattern += "(";
                    optionalCount++;
                }
                if (hasWrittenComponent) {
                    subpattern += ts.directorySeparator;
                }
                if (usage !== "exclude") {
                    var componentPattern = "";
                    // The * and ? wildcards should not match directories or files that start with . if they
                    // appear first in a component. Dotted directories and files can be included explicitly
                    // like so: **/.*/.*
                    if (component.charCodeAt(0) === 42 /* asterisk */) {
                        componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
                        component = component.substr(1);
                    }
                    else if (component.charCodeAt(0) === 63 /* question */) {
                        componentPattern += "[^./]";
                        component = component.substr(1);
                    }
                    componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                    // Patterns should not include subfolders like node_modules unless they are
                    // explicitly included as part of the path.
                    //
                    // As an optimization, if the component pattern is the same as the component,
                    // then there definitely were no wildcard characters and we do not need to
                    // add the exclusion pattern.
                    if (componentPattern !== component) {
                        subpattern += implicitExcludePathRegexPattern;
                    }
                    subpattern += componentPattern;
                }
                else {
                    subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                }
            }
            hasWrittenComponent = true;
        }
        while (optionalCount > 0) {
            subpattern += ")?";
            optionalCount--;
        }
        return subpattern;
    }
    function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
        return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match;
    }
    function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
        path = normalizePath(path);
        currentDirectory = normalizePath(currentDirectory);
        var absolutePath = combinePaths(currentDirectory, path);
        return {
            includeFilePatterns: map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), function (pattern) { return "^" + pattern + "$"; }),
            includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"),
            includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"),
            excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"),
            basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames)
        };
    }
    ts.getFileMatcherPatterns = getFileMatcherPatterns;
    function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries) {
        path = normalizePath(path);
        currentDirectory = normalizePath(currentDirectory);
        var patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
        var regexFlag = useCaseSensitiveFileNames ? "" : "i";
        var includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(function (pattern) { return new RegExp(pattern, regexFlag); });
        var includeDirectoryRegex = patterns.includeDirectoryPattern && new RegExp(patterns.includeDirectoryPattern, regexFlag);
        var excludeRegex = patterns.excludePattern && new RegExp(patterns.excludePattern, regexFlag);
        // Associate an array of results with each include regex. This keeps results in order of the "include" order.
        // If there are no "includes", then just put everything in results[0].
        var results = includeFileRegexes ? includeFileRegexes.map(function () { return []; }) : [[]];
        var comparer = useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive;
        for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) {
            var basePath = _a[_i];
            visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
        }
        return flatten(results);
        function visitDirectory(path, absolutePath, depth) {
            var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories;
            files = files.slice().sort(comparer);
            var _loop_1 = function (current) {
                var name = combinePaths(path, current);
                var absoluteName = combinePaths(absolutePath, current);
                if (extensions && !fileExtensionIsOneOf(name, extensions))
                    return "continue";
                if (excludeRegex && excludeRegex.test(absoluteName))
                    return "continue";
                if (!includeFileRegexes) {
                    results[0].push(name);
                }
                else {
                    var includeIndex = findIndex(includeFileRegexes, function (re) { return re.test(absoluteName); });
                    if (includeIndex !== -1) {
                        results[includeIndex].push(name);
                    }
                }
            };
            for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
                var current = files_1[_i];
                _loop_1(current);
            }
            if (depth !== undefined) {
                depth--;
                if (depth === 0) {
                    return;
                }
            }
            directories = directories.slice().sort(comparer);
            for (var _b = 0, directories_1 = directories; _b < directories_1.length; _b++) {
                var current = directories_1[_b];
                var name = combinePaths(path, current);
                var absoluteName = combinePaths(absolutePath, current);
                if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
                    visitDirectory(name, absoluteName, depth);
                }
            }
        }
    }
    ts.matchFiles = matchFiles;
    /**
     * Computes the unique non-wildcard base paths amongst the provided include patterns.
     */
    function getBasePaths(path, includes, useCaseSensitiveFileNames) {
        // Storage for our results in the form of literal paths (e.g. the paths as written by the user).
        var basePaths = [path];
        if (includes) {
            // Storage for literal base paths amongst the include patterns.
            var includeBasePaths = [];
            for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) {
                var include = includes_1[_i];
                // We also need to check the relative paths by converting them to absolute and normalizing
                // in case they escape the base path (e.g "..\somedirectory")
                var absolute = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include));
                // Append the literal and canonical candidate base paths.
                includeBasePaths.push(getIncludeBasePath(absolute));
            }
            // Sort the offsets array using either the literal or canonical path representations.
            includeBasePaths.sort(useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive);
            var _loop_2 = function (includeBasePath) {
                if (ts.every(basePaths, function (basePath) { return !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames); })) {
                    basePaths.push(includeBasePath);
                }
            };
            // Iterate over each include base path and include unique base paths that are not a
            // subpath of an existing base path
            for (var _a = 0, includeBasePaths_1 = includeBasePaths; _a < includeBasePaths_1.length; _a++) {
                var includeBasePath = includeBasePaths_1[_a];
                _loop_2(includeBasePath);
            }
        }
        return basePaths;
    }
    function getIncludeBasePath(absolute) {
        var wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
        if (wildcardOffset < 0) {
            // No "*" or "?" in the path
            return !hasExtension(absolute)
                ? absolute
                : removeTrailingDirectorySeparator(getDirectoryPath(absolute));
        }
        return absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset));
    }
    function ensureScriptKind(fileName, scriptKind) {
        // Using scriptKind as a condition handles both:
        // - 'scriptKind' is unspecified and thus it is `undefined`
        // - 'scriptKind' is set and it is `Unknown` (0)
        // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
        // to get the ScriptKind from the file name. If it cannot be resolved
        // from the file name then the default 'TS' script kind is returned.
        return scriptKind || getScriptKindFromFileName(fileName) || 3 /* TS */;
    }
    ts.ensureScriptKind = ensureScriptKind;
    function getScriptKindFromFileName(fileName) {
        var ext = fileName.substr(fileName.lastIndexOf("."));
        switch (ext.toLowerCase()) {
            case ".js" /* Js */:
                return 1 /* JS */;
            case ".jsx" /* Jsx */:
                return 2 /* JSX */;
            case ".ts" /* Ts */:
                return 3 /* TS */;
            case ".tsx" /* Tsx */:
                return 4 /* TSX */;
            case ".json" /* Json */:
                return 6 /* JSON */;
            default:
                return 0 /* Unknown */;
        }
    }
    ts.getScriptKindFromFileName = getScriptKindFromFileName;
    /**
     *  List of supported extensions in order of file resolution precedence.
     */
    ts.supportedTypeScriptExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */];
    /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
    ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */];
    ts.supportedJavascriptExtensions = [".js" /* Js */, ".jsx" /* Jsx */];
    var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions);
    function getSupportedExtensions(options, extraFileExtensions) {
        var needAllExtensions = options && options.allowJs;
        if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
            return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions;
        }
        return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; })));
    }
    ts.getSupportedExtensions = getSupportedExtensions;
    function hasJavaScriptFileExtension(fileName) {
        return forEach(ts.supportedJavascriptExtensions, function (extension) { return fileExtensionIs(fileName, extension); });
    }
    ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
    function hasTypeScriptFileExtension(fileName) {
        return forEach(ts.supportedTypeScriptExtensions, function (extension) { return fileExtensionIs(fileName, extension); });
    }
    ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension;
    function isSupportedSourceFileName(fileName, compilerOptions, extraFileExtensions) {
        if (!fileName) {
            return false;
        }
        for (var _i = 0, _a = getSupportedExtensions(compilerOptions, extraFileExtensions); _i < _a.length; _i++) {
            var extension = _a[_i];
            if (fileExtensionIs(fileName, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.isSupportedSourceFileName = isSupportedSourceFileName;
    /**
     * Extension boundaries by priority. Lower numbers indicate higher priorities, and are
     * aligned to the offset of the highest priority extension in the
     * allSupportedExtensions array.
     */
    var ExtensionPriority;
    (function (ExtensionPriority) {
        ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles";
        ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles";
        ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest";
        ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest";
    })(ExtensionPriority = ts.ExtensionPriority || (ts.ExtensionPriority = {}));
    function getExtensionPriority(path, supportedExtensions) {
        for (var i = supportedExtensions.length - 1; i >= 0; i--) {
            if (fileExtensionIs(path, supportedExtensions[i])) {
                return adjustExtensionPriority(i, supportedExtensions);
            }
        }
        // If its not in the list of supported extensions, this is likely a
        // TypeScript file with a non-ts extension
        return 0 /* Highest */;
    }
    ts.getExtensionPriority = getExtensionPriority;
    /**
     * Adjusts an extension priority to be the highest priority within the same range.
     */
    function adjustExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 0 /* TypeScriptFiles */;
        }
        else if (extensionPriority < supportedExtensions.length) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.adjustExtensionPriority = adjustExtensionPriority;
    /**
     * Gets the next lowest extension priority for a given priority.
     */
    function getNextLowestExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority;
    var extensionsToRemove = [".d.ts" /* Dts */, ".ts" /* Ts */, ".js" /* Js */, ".tsx" /* Tsx */, ".jsx" /* Jsx */];
    function removeFileExtension(path) {
        for (var _i = 0, extensionsToRemove_1 = extensionsToRemove; _i < extensionsToRemove_1.length; _i++) {
            var ext = extensionsToRemove_1[_i];
            var extensionless = tryRemoveExtension(path, ext);
            if (extensionless !== undefined) {
                return extensionless;
            }
        }
        return path;
    }
    ts.removeFileExtension = removeFileExtension;
    function tryRemoveExtension(path, extension) {
        return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
    }
    ts.tryRemoveExtension = tryRemoveExtension;
    function removeExtension(path, extension) {
        return path.substring(0, path.length - extension.length);
    }
    ts.removeExtension = removeExtension;
    function changeExtension(path, newExtension) {
        return (removeFileExtension(path) + newExtension);
    }
    ts.changeExtension = changeExtension;
    function Symbol(flags, name) {
        this.flags = flags;
        this.escapedName = name;
        this.declarations = undefined;
    }
    function Type(checker, flags) {
        this.flags = flags;
        if (Debug.isDebugging) {
            this.checker = checker;
        }
    }
    function Signature() {
    }
    function Node(kind, pos, end) {
        this.id = 0;
        this.kind = kind;
        this.pos = pos;
        this.end = end;
        this.flags = 0 /* None */;
        this.modifierFlagsCache = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
        this.original = undefined;
    }
    function SourceMapSource(fileName, text, skipTrivia) {
        this.fileName = fileName;
        this.text = text;
        this.skipTrivia = skipTrivia || (function (pos) { return pos; });
    }
    ts.objectAllocator = {
        getNodeConstructor: function () { return Node; },
        getTokenConstructor: function () { return Node; },
        getIdentifierConstructor: function () { return Node; },
        getSourceFileConstructor: function () { return Node; },
        getSymbolConstructor: function () { return Symbol; },
        getTypeConstructor: function () { return Type; },
        getSignatureConstructor: function () { return Signature; },
        getSourceMapSourceConstructor: function () { return SourceMapSource; },
    };
    var AssertionLevel;
    (function (AssertionLevel) {
        AssertionLevel[AssertionLevel["None"] = 0] = "None";
        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
    })(AssertionLevel = ts.AssertionLevel || (ts.AssertionLevel = {}));
    var Debug;
    (function (Debug) {
        Debug.currentAssertionLevel = 0 /* None */;
        Debug.isDebugging = false;
        function shouldAssert(level) {
            return Debug.currentAssertionLevel >= level;
        }
        Debug.shouldAssert = shouldAssert;
        function assert(expression, message, verboseDebugInfo, stackCrawlMark) {
            if (!expression) {
                if (verboseDebugInfo) {
                    message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
                }
                fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert);
            }
        }
        Debug.assert = assert;
        function assertEqual(a, b, msg, msg2) {
            if (a !== b) {
                var message = msg ? msg2 ? msg + " " + msg2 : msg : "";
                fail("Expected " + a + " === " + b + ". " + message);
            }
        }
        Debug.assertEqual = assertEqual;
        function assertLessThan(a, b, msg) {
            if (a >= b) {
                fail("Expected " + a + " < " + b + ". " + (msg || ""));
            }
        }
        Debug.assertLessThan = assertLessThan;
        function assertLessThanOrEqual(a, b) {
            if (a > b) {
                fail("Expected " + a + " <= " + b);
            }
        }
        Debug.assertLessThanOrEqual = assertLessThanOrEqual;
        function assertGreaterThanOrEqual(a, b) {
            if (a < b) {
                fail("Expected " + a + " >= " + b);
            }
        }
        Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual;
        function fail(message, stackCrawlMark) {
            debugger;
            var e = new Error(message ? "Debug Failure. " + message : "Debug Failure.");
            if (Error.captureStackTrace) {
                Error.captureStackTrace(e, stackCrawlMark || fail);
            }
            throw e;
        }
        Debug.fail = fail;
        function assertNever(member, message, stackCrawlMark) {
            return fail(message || "Illegal value: " + member, stackCrawlMark || assertNever);
        }
        Debug.assertNever = assertNever;
        function getFunctionName(func) {
            if (typeof func !== "function") {
                return "";
            }
            else if (func.hasOwnProperty("name")) {
                return func.name;
            }
            else {
                var text = Function.prototype.toString.call(func);
                var match = /^function\s+([\w\$]+)\s*\(/.exec(text);
                return match ? match[1] : "";
            }
        }
        Debug.getFunctionName = getFunctionName;
    })(Debug = ts.Debug || (ts.Debug = {}));
    /** Remove an item from an array, moving everything to its right one space left. */
    function orderedRemoveItem(array, item) {
        for (var i = 0; i < array.length; i++) {
            if (array[i] === item) {
                orderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    ts.orderedRemoveItem = orderedRemoveItem;
    /** Remove an item by index from an array, moving everything to its right one space left. */
    function orderedRemoveItemAt(array, index) {
        // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
        for (var i = index; i < array.length - 1; i++) {
            array[i] = array[i + 1];
        }
        array.pop();
    }
    ts.orderedRemoveItemAt = orderedRemoveItemAt;
    function unorderedRemoveItemAt(array, index) {
        // Fill in the "hole" left at `index`.
        array[index] = array[array.length - 1];
        array.pop();
    }
    ts.unorderedRemoveItemAt = unorderedRemoveItemAt;
    /** Remove the *first* occurrence of `item` from the array. */
    function unorderedRemoveItem(array, item) {
        unorderedRemoveFirstItemWhere(array, function (element) { return element === item; });
    }
    ts.unorderedRemoveItem = unorderedRemoveItem;
    /** Remove the *first* element satisfying `predicate`. */
    function unorderedRemoveFirstItemWhere(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                unorderedRemoveItemAt(array, i);
                break;
            }
        }
    }
    function createGetCanonicalFileName(useCaseSensitiveFileNames) {
        return useCaseSensitiveFileNames
            ? (function (fileName) { return fileName; })
            : (function (fileName) { return fileName.toLowerCase(); });
    }
    ts.createGetCanonicalFileName = createGetCanonicalFileName;
    /**
     * patternStrings contains both pattern strings (containing "*") and regular strings.
     * Return an exact match if possible, or a pattern match, or undefined.
     * (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
     */
    function matchPatternOrExact(patternStrings, candidate) {
        var patterns = [];
        for (var _i = 0, patternStrings_1 = patternStrings; _i < patternStrings_1.length; _i++) {
            var patternString = patternStrings_1[_i];
            var pattern = tryParsePattern(patternString);
            if (pattern) {
                patterns.push(pattern);
            }
            else if (patternString === candidate) {
                // pattern was matched as is - no need to search further
                return patternString;
            }
        }
        return findBestPatternMatch(patterns, function (_) { return _; }, candidate);
    }
    ts.matchPatternOrExact = matchPatternOrExact;
    function patternText(_a) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return prefix + "*" + suffix;
    }
    ts.patternText = patternText;
    /**
     * Given that candidate matches pattern, returns the text matching the '*'.
     * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
     */
    function matchedText(pattern, candidate) {
        Debug.assert(isPatternMatch(pattern, candidate));
        return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
    }
    ts.matchedText = matchedText;
    /** Return the object corresponding to the best pattern to match `candidate`. */
    function findBestPatternMatch(values, getPattern, candidate) {
        var matchedValue = undefined;
        // use length of prefix as betterness criteria
        var longestMatchPrefixLength = -1;
        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
            var v = values_1[_i];
            var pattern = getPattern(v);
            if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
                longestMatchPrefixLength = pattern.prefix.length;
                matchedValue = v;
            }
        }
        return matchedValue;
    }
    ts.findBestPatternMatch = findBestPatternMatch;
    function isPatternMatch(_a, candidate) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return candidate.length >= prefix.length + suffix.length &&
            startsWith(candidate, prefix) &&
            endsWith(candidate, suffix);
    }
    function tryParsePattern(pattern) {
        // This should be verified outside of here and a proper error thrown.
        Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
        var indexOfStar = pattern.indexOf("*");
        return indexOfStar === -1 ? undefined : {
            prefix: pattern.substr(0, indexOfStar),
            suffix: pattern.substr(indexOfStar + 1)
        };
    }
    ts.tryParsePattern = tryParsePattern;
    function positionIsSynthesized(pos) {
        // This is a fast way of testing the following conditions:
        //  pos === undefined || pos === null || isNaN(pos) || pos < 0;
        return !(pos >= 0);
    }
    ts.positionIsSynthesized = positionIsSynthesized;
    /** True if an extension is one of the supported TypeScript extensions. */
    function extensionIsTypeScript(ext) {
        return ext === ".ts" /* Ts */ || ext === ".tsx" /* Tsx */ || ext === ".d.ts" /* Dts */;
    }
    ts.extensionIsTypeScript = extensionIsTypeScript;
    /**
     * Gets the extension from a path.
     * Path must have a valid extension.
     */
    function extensionFromPath(path) {
        var ext = tryGetExtensionFromPath(path);
        if (ext !== undefined) {
            return ext;
        }
        Debug.fail("File " + path + " has unknown extension.");
    }
    ts.extensionFromPath = extensionFromPath;
    function isAnySupportedFileExtension(path) {
        return tryGetExtensionFromPath(path) !== undefined;
    }
    ts.isAnySupportedFileExtension = isAnySupportedFileExtension;
    function tryGetExtensionFromPath(path) {
        return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); });
    }
    ts.tryGetExtensionFromPath = tryGetExtensionFromPath;
    // Retrieves any string from the final "." onwards from a base file name.
    // Unlike extensionFromPath, which throws an exception on unrecognized extensions.
    function getAnyExtensionFromPath(path) {
        var baseFileName = getBaseFileName(path);
        var extensionIndex = baseFileName.lastIndexOf(".");
        if (extensionIndex >= 0) {
            return baseFileName.substring(extensionIndex);
        }
    }
    ts.getAnyExtensionFromPath = getAnyExtensionFromPath;
    function isCheckJsEnabledForFile(sourceFile, compilerOptions) {
        return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
    }
    ts.isCheckJsEnabledForFile = isCheckJsEnabledForFile;
    function and(f, g) {
        return function (arg) { return f(arg) && g(arg); };
    }
    ts.and = and;
    function assertTypeIsNever(_) { }
    ts.assertTypeIsNever = assertTypeIsNever;
    function createCachedDirectoryStructureHost(host) {
        var cachedReadDirectoryResult = createMap();
        var getCurrentDirectory = memoize(function () { return host.getCurrentDirectory(); });
        var getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        return {
            useCaseSensitiveFileNames: host.useCaseSensitiveFileNames,
            newLine: host.newLine,
            readFile: function (path, encoding) { return host.readFile(path, encoding); },
            write: function (s) { return host.write(s); },
            writeFile: writeFile,
            fileExists: fileExists,
            directoryExists: directoryExists,
            createDirectory: createDirectory,
            getCurrentDirectory: getCurrentDirectory,
            getDirectories: getDirectories,
            readDirectory: readDirectory,
            addOrDeleteFileOrDirectory: addOrDeleteFileOrDirectory,
            addOrDeleteFile: addOrDeleteFile,
            clearCache: clearCache,
            exit: function (code) { return host.exit(code); }
        };
        function toPath(fileName) {
            return ts.toPath(fileName, getCurrentDirectory(), getCanonicalFileName);
        }
        function getCachedFileSystemEntries(rootDirPath) {
            return cachedReadDirectoryResult.get(rootDirPath);
        }
        function getCachedFileSystemEntriesForBaseDir(path) {
            return getCachedFileSystemEntries(getDirectoryPath(path));
        }
        function getBaseNameOfFileName(fileName) {
            return getBaseFileName(normalizePath(fileName));
        }
        function createCachedFileSystemEntries(rootDir, rootDirPath) {
            var resultFromHost = {
                files: map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/ ["*.*"]), getBaseNameOfFileName) || [],
                directories: host.getDirectories(rootDir) || []
            };
            cachedReadDirectoryResult.set(rootDirPath, resultFromHost);
            return resultFromHost;
        }
        /**
         * If the readDirectory result was already cached, it returns that
         * Otherwise gets result from host and caches it.
         * The host request is done under try catch block to avoid caching incorrect result
         */
        function tryReadDirectory(rootDir, rootDirPath) {
            var cachedResult = getCachedFileSystemEntries(rootDirPath);
            if (cachedResult) {
                return cachedResult;
            }
            try {
                return createCachedFileSystemEntries(rootDir, rootDirPath);
            }
            catch (_e) {
                // If there is exception to read directories, dont cache the result and direct the calls to host
                Debug.assert(!cachedReadDirectoryResult.has(rootDirPath));
                return undefined;
            }
        }
        function fileNameEqual(name1, name2) {
            return getCanonicalFileName(name1) === getCanonicalFileName(name2);
        }
        function hasEntry(entries, name) {
            return some(entries, function (file) { return fileNameEqual(file, name); });
        }
        function updateFileSystemEntry(entries, baseName, isValid) {
            if (hasEntry(entries, baseName)) {
                if (!isValid) {
                    return filterMutate(entries, function (entry) { return !fileNameEqual(entry, baseName); });
                }
            }
            else if (isValid) {
                return entries.push(baseName);
            }
        }
        function writeFile(fileName, data, writeByteOrderMark) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            if (result) {
                updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
            }
            return host.writeFile(fileName, data, writeByteOrderMark);
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
                host.fileExists(fileName);
        }
        function directoryExists(dirPath) {
            var path = toPath(dirPath);
            return cachedReadDirectoryResult.has(path) || host.directoryExists(dirPath);
        }
        function createDirectory(dirPath) {
            var path = toPath(dirPath);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            var baseFileName = getBaseNameOfFileName(dirPath);
            if (result) {
                updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
            }
            host.createDirectory(dirPath);
        }
        function getDirectories(rootDir) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return result.directories.slice();
            }
            return host.getDirectories(rootDir);
        }
        function readDirectory(rootDir, extensions, excludes, includes, depth) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return matchFiles(rootDir, extensions, excludes, includes, host.useCaseSensitiveFileNames, getCurrentDirectory(), depth, getFileSystemEntries);
            }
            return host.readDirectory(rootDir, extensions, excludes, includes, depth);
            function getFileSystemEntries(dir) {
                var path = toPath(dir);
                if (path === rootDirPath) {
                    return result;
                }
                return getCachedFileSystemEntries(path) || createCachedFileSystemEntries(dir, path);
            }
        }
        function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) {
            var existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
            if (existingResult) {
                // This was a folder already present, remove it if this doesnt exist any more
                if (!host.directoryExists(fileOrDirectory)) {
                    cachedReadDirectoryResult.delete(fileOrDirectoryPath);
                }
            }
            else {
                // This was earlier a file (hence not in cached directory contents)
                // or we never cached the directory containing it
                var parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
                if (parentResult) {
                    var baseName = getBaseNameOfFileName(fileOrDirectory);
                    if (parentResult) {
                        var fsQueryResult = {
                            fileExists: host.fileExists(fileOrDirectoryPath),
                            directoryExists: host.directoryExists(fileOrDirectoryPath)
                        };
                        updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
                        updateFileSystemEntry(parentResult.directories, baseName, fsQueryResult.directoryExists);
                        return fsQueryResult;
                    }
                }
            }
        }
        function addOrDeleteFile(fileName, filePath, eventKind) {
            if (eventKind === ts.FileWatcherEventKind.Changed) {
                return;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
            if (parentResult) {
                updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === ts.FileWatcherEventKind.Created);
            }
        }
        function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists) {
            updateFileSystemEntry(parentResult.files, baseName, fileExists);
        }
        function clearCache() {
            cachedReadDirectoryResult.clear();
        }
    }
    ts.createCachedDirectoryStructureHost = createCachedDirectoryStructureHost;
})(ts || (ts = {}));
/// <reference path="core.ts"/>
var ts;
(function (ts) {
    /**
     * Set a high stack trace limit to provide more information in case of an error.
     * Called for command-line and server use cases.
     * Not called if TypeScript is used as a library.
     */
    /* @internal */
    function setStackTraceLimit() {
        if (Error.stackTraceLimit < 100) {
            Error.stackTraceLimit = 100;
        }
    }
    ts.setStackTraceLimit = setStackTraceLimit;
    var FileWatcherEventKind;
    (function (FileWatcherEventKind) {
        FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created";
        FileWatcherEventKind[FileWatcherEventKind["Changed"] = 1] = "Changed";
        FileWatcherEventKind[FileWatcherEventKind["Deleted"] = 2] = "Deleted";
    })(FileWatcherEventKind = ts.FileWatcherEventKind || (ts.FileWatcherEventKind = {}));
    function getNodeMajorVersion() {
        if (typeof process === "undefined") {
            return undefined;
        }
        var version = process.version;
        if (!version) {
            return undefined;
        }
        var dot = version.indexOf(".");
        if (dot === -1) {
            return undefined;
        }
        return parseInt(version.substring(1, dot));
    }
    ts.getNodeMajorVersion = getNodeMajorVersion;
    ts.sys = (function () {
        function getNodeSystem() {
            var _fs = require("fs");
            var _path = require("path");
            var _os = require("os");
            var _crypto = require("crypto");
            var useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER;
            function createWatchedFileSet() {
                var dirWatchers = ts.createMap();
                // One file can have multiple watchers
                var fileWatcherCallbacks = ts.createMultiMap();
                return { addFile: addFile, removeFile: removeFile };
                function reduceDirWatcherRefCountForFile(fileName) {
                    var dirName = ts.getDirectoryPath(fileName);
                    var watcher = dirWatchers.get(dirName);
                    if (watcher) {
                        watcher.referenceCount -= 1;
                        if (watcher.referenceCount <= 0) {
                            watcher.close();
                            dirWatchers.delete(dirName);
                        }
                    }
                }
                function addDirWatcher(dirPath) {
                    var watcher = dirWatchers.get(dirPath);
                    if (watcher) {
                        watcher.referenceCount += 1;
                        return;
                    }
                    watcher = fsWatchDirectory(dirPath || ".", function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); });
                    watcher.referenceCount = 1;
                    dirWatchers.set(dirPath, watcher);
                    return;
                }
                function addFileWatcherCallback(filePath, callback) {
                    fileWatcherCallbacks.add(filePath, callback);
                }
                function addFile(fileName, callback) {
                    addFileWatcherCallback(fileName, callback);
                    addDirWatcher(ts.getDirectoryPath(fileName));
                    return { fileName: fileName, callback: callback };
                }
                function removeFile(watchedFile) {
                    removeFileWatcherCallback(watchedFile.fileName, watchedFile.callback);
                    reduceDirWatcherRefCountForFile(watchedFile.fileName);
                }
                function removeFileWatcherCallback(filePath, callback) {
                    fileWatcherCallbacks.remove(filePath, callback);
                }
                function fileEventHandler(eventName, relativeFileName, baseDirPath) {
                    // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
                    var fileName = !ts.isString(relativeFileName)
                        ? undefined
                        : ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath);
                    // Some applications save a working file via rename operations
                    if ((eventName === "change" || eventName === "rename")) {
                        var callbacks = fileWatcherCallbacks.get(fileName);
                        if (callbacks) {
                            for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
                                var fileCallback = callbacks_1[_i];
                                fileCallback(fileName, FileWatcherEventKind.Changed);
                            }
                        }
                    }
                }
            }
            var watchedFileSet = createWatchedFileSet();
            var nodeVersion = getNodeMajorVersion();
            var isNode4OrLater = nodeVersion >= 4;
            function isFileSystemCaseSensitive() {
                // win32\win64 are case insensitive platforms
                if (platform === "win32" || platform === "win64") {
                    return false;
                }
                // If this file exists under a different case, we must be case-insensitve.
                return !fileExists(swapCase(__filename));
            }
            /** Convert all lowercase chars to uppercase, and vice-versa */
            function swapCase(s) {
                return s.replace(/\w/g, function (ch) {
                    var up = ch.toUpperCase();
                    return ch === up ? ch.toLowerCase() : up;
                });
            }
            var platform = _os.platform();
            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
            function fsWatchFile(fileName, callback, pollingInterval) {
                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval || 250 }, fileChanged);
                return {
                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
                };
                function fileChanged(curr, prev) {
                    var isCurrZero = +curr.mtime === 0;
                    var isPrevZero = +prev.mtime === 0;
                    var created = !isCurrZero && isPrevZero;
                    var deleted = isCurrZero && !isPrevZero;
                    var eventKind = created
                        ? FileWatcherEventKind.Created
                        : deleted
                            ? FileWatcherEventKind.Deleted
                            : FileWatcherEventKind.Changed;
                    if (eventKind === FileWatcherEventKind.Changed && +curr.mtime <= +prev.mtime) {
                        return;
                    }
                    callback(fileName, eventKind);
                }
            }
            function fsWatchDirectory(directoryName, callback, recursive) {
                var options;
                /** Watcher for the directory depending on whether it is missing or present */
                var watcher = !directoryExists(directoryName) ?
                    watchMissingDirectory() :
                    watchPresentDirectory();
                return {
                    close: function () {
                        // Close the watcher (either existing directory watcher or missing directory watcher)
                        watcher.close();
                    }
                };
                /**
                 * Watch the directory that is currently present
                 * and when the watched directory is deleted, switch to missing directory watcher
                 */
                function watchPresentDirectory() {
                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                    if (options === undefined) {
                        if (isNode4OrLater && (process.platform === "win32" || process.platform === "darwin")) {
                            options = { persistent: true, recursive: !!recursive };
                        }
                        else {
                            options = { persistent: true };
                        }
                    }
                    var dirWatcher = _fs.watch(directoryName, options, callback);
                    dirWatcher.on("error", function () {
                        if (!directoryExists(directoryName)) {
                            // Deleting directory
                            watcher = watchMissingDirectory();
                            // Call the callback for current directory
                            callback("rename", "");
                        }
                    });
                    return dirWatcher;
                }
                /**
                 * Watch the directory that is missing
                 * and switch to existing directory when the directory is created
                 */
                function watchMissingDirectory() {
                    return fsWatchFile(directoryName, function (_fileName, eventKind) {
                        if (eventKind === FileWatcherEventKind.Created && directoryExists(directoryName)) {
                            watcher.close();
                            watcher = watchPresentDirectory();
                            // Call the callback for current directory
                            // For now it could be callback for the inner directory creation,
                            // but just return current directory, better than current no-op
                            callback("rename", "");
                        }
                    });
                }
            }
            function readFile(fileName, _encoding) {
                if (!fileExists(fileName)) {
                    return undefined;
                }
                var buffer = _fs.readFileSync(fileName);
                var len = buffer.length;
                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
                    // flip all byte pairs and treat as little endian.
                    len &= ~1; // Round down to a multiple of 2
                    for (var i = 0; i < len; i += 2) {
                        var temp = buffer[i];
                        buffer[i] = buffer[i + 1];
                        buffer[i + 1] = temp;
                    }
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
                    // Little endian UTF-16 byte order mark detected
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
                    // UTF-8 byte order mark detected
                    return buffer.toString("utf8", 3);
                }
                // Default is UTF-8 with no byte order mark
                return buffer.toString("utf8");
            }
            function writeFile(fileName, data, writeByteOrderMark) {
                // If a BOM is required, emit one
                if (writeByteOrderMark) {
                    data = "\uFEFF" + data;
                }
                var fd;
                try {
                    fd = _fs.openSync(fileName, "w");
                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
                }
                finally {
                    if (fd !== undefined) {
                        _fs.closeSync(fd);
                    }
                }
            }
            function getAccessibleFileSystemEntries(path) {
                try {
                    var entries = _fs.readdirSync(path || ".").sort();
                    var files = [];
                    var directories = [];
                    for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
                        var entry = entries_1[_i];
                        // This is necessary because on some file system node fails to exclude
                        // "." and "..". See https://github.com/nodejs/node/issues/4002
                        if (entry === "." || entry === "..") {
                            continue;
                        }
                        var name = ts.combinePaths(path, entry);
                        var stat = void 0;
                        try {
                            stat = _fs.statSync(name);
                        }
                        catch (e) {
                            continue;
                        }
                        if (stat.isFile()) {
                            files.push(entry);
                        }
                        else if (stat.isDirectory()) {
                            directories.push(entry);
                        }
                    }
                    return { files: files, directories: directories };
                }
                catch (e) {
                    return { files: [], directories: [] };
                }
            }
            function readDirectory(path, extensions, excludes, includes, depth) {
                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries);
            }
            var FileSystemEntryKind;
            (function (FileSystemEntryKind) {
                FileSystemEntryKind[FileSystemEntryKind["File"] = 0] = "File";
                FileSystemEntryKind[FileSystemEntryKind["Directory"] = 1] = "Directory";
            })(FileSystemEntryKind || (FileSystemEntryKind = {}));
            function fileSystemEntryExists(path, entryKind) {
                try {
                    var stat = _fs.statSync(path);
                    switch (entryKind) {
                        case 0 /* File */: return stat.isFile();
                        case 1 /* Directory */: return stat.isDirectory();
                    }
                }
                catch (e) {
                    return false;
                }
            }
            function fileExists(path) {
                return fileSystemEntryExists(path, 0 /* File */);
            }
            function directoryExists(path) {
                return fileSystemEntryExists(path, 1 /* Directory */);
            }
            function getDirectories(path) {
                return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); });
            }
            var nodeSystem = {
                args: process.argv.slice(2),
                newLine: _os.EOL,
                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                write: function (s) {
                    process.stdout.write(s);
                },
                readFile: readFile,
                writeFile: writeFile,
                watchFile: function (fileName, callback, pollingInterval) {
                    if (useNonPollingWatchers) {
                        var watchedFile_1 = watchedFileSet.addFile(fileName, callback);
                        return {
                            close: function () { return watchedFileSet.removeFile(watchedFile_1); }
                        };
                    }
                    else {
                        return fsWatchFile(fileName, callback, pollingInterval);
                    }
                },
                watchDirectory: function (directoryName, callback, recursive) {
                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                    return fsWatchDirectory(directoryName, function (eventName, relativeFileName) {
                        // In watchDirectory we only care about adding and removing files (when event name is
                        // "rename"); changes made within files are handled by corresponding fileWatchers (when
                        // event name is "change")
                        if (eventName === "rename") {
                            // When deleting a file, the passed baseFileName is null
                            callback(!relativeFileName ? relativeFileName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName)));
                        }
                    }, recursive);
                },
                resolvePath: function (path) { return _path.resolve(path); },
                fileExists: fileExists,
                directoryExists: directoryExists,
                createDirectory: function (directoryName) {
                    if (!nodeSystem.directoryExists(directoryName)) {
                        _fs.mkdirSync(directoryName);
                    }
                },
                getExecutingFilePath: function () {
                    return __filename;
                },
                getCurrentDirectory: function () {
                    return process.cwd();
                },
                getDirectories: getDirectories,
                getEnvironmentVariable: function (name) {
                    return process.env[name] || "";
                },
                readDirectory: readDirectory,
                getModifiedTime: function (path) {
                    try {
                        return _fs.statSync(path).mtime;
                    }
                    catch (e) {
                        return undefined;
                    }
                },
                createHash: function (data) {
                    var hash = _crypto.createHash("md5");
                    hash.update(data);
                    return hash.digest("hex");
                },
                getMemoryUsage: function () {
                    if (global.gc) {
                        global.gc();
                    }
                    return process.memoryUsage().heapUsed;
                },
                getFileSize: function (path) {
                    try {
                        var stat = _fs.statSync(path);
                        if (stat.isFile()) {
                            return stat.size;
                        }
                    }
                    catch (e) { }
                    return 0;
                },
                exit: function (exitCode) {
                    process.exit(exitCode);
                },
                realpath: function (path) {
                    return _fs.realpathSync(path);
                },
                debugMode: ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
                tryEnableSourceMapsForHost: function () {
                    try {
                        require("source-map-support").install();
                    }
                    catch (e) {
                        // Could not enable source maps.
                    }
                },
                setTimeout: setTimeout,
                clearTimeout: clearTimeout
            };
            return nodeSystem;
        }
        function getChakraSystem() {
            var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); });
            return {
                newLine: ChakraHost.newLine || "\r\n",
                args: ChakraHost.args,
                useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
                write: ChakraHost.echo,
                readFile: function (path, _encoding) {
                    // encoding is automatically handled by the implementation in ChakraHost
                    return ChakraHost.readFile(path);
                },
                writeFile: function (path, data, writeByteOrderMark) {
                    // If a BOM is required, emit one
                    if (writeByteOrderMark) {
                        data = "\uFEFF" + data;
                    }
                    ChakraHost.writeFile(path, data);
                },
                resolvePath: ChakraHost.resolvePath,
                fileExists: ChakraHost.fileExists,
                directoryExists: ChakraHost.directoryExists,
                createDirectory: ChakraHost.createDirectory,
                getExecutingFilePath: function () { return ChakraHost.executingFile; },
                getCurrentDirectory: function () { return ChakraHost.currentDirectory; },
                getDirectories: ChakraHost.getDirectories,
                getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (function () { return ""; }),
                readDirectory: function (path, extensions, excludes, includes, _depth) {
                    var pattern = ts.getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
                    return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
                },
                exit: ChakraHost.quit,
                realpath: realpath
            };
        }
        function recursiveCreateDirectory(directoryPath, sys) {
            var basePath = ts.getDirectoryPath(directoryPath);
            var shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
            if (shouldCreateParent) {
                recursiveCreateDirectory(basePath, sys);
            }
            if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
                sys.createDirectory(directoryPath);
            }
        }
        var sys;
        if (typeof ChakraHost !== "undefined") {
            sys = getChakraSystem();
        }
        else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
            // process and process.nextTick checks if current environment is node-like
            // process.browser check excludes webpack and browserify
            sys = getNodeSystem();
        }
        if (sys) {
            // patch writefile to create folder before writing the file
            var originalWriteFile_1 = sys.writeFile;
            sys.writeFile = function (path, data, writeBom) {
                var directoryPath = ts.getDirectoryPath(ts.normalizeSlashes(path));
                if (directoryPath && !sys.directoryExists(directoryPath)) {
                    recursiveCreateDirectory(directoryPath, sys);
                }
                originalWriteFile_1.call(sys, path, data, writeBom);
            };
        }
        return sys;
    })();
    if (ts.sys && ts.sys.getEnvironmentVariable) {
        ts.Debug.currentAssertionLevel = /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))
            ? 1 /* Normal */
            : 0 /* None */;
    }
    if (ts.sys && ts.sys.debugMode) {
        ts.Debug.isDebugging = true;
    }
})(ts || (ts = {}));
// <auto-generated />
/// <reference path="types.ts" />
/* @internal */
var ts;
(function (ts) {
    function diag(code, category, key, message) {
        return { code: code, category: category, key: key, message: message };
    }
    ts.Diagnostics = {
        Unterminated_string_literal: diag(1002, ts.DiagnosticCategory.Error, "Unterminated_string_literal_1002", "Unterminated string literal."),
        Identifier_expected: diag(1003, ts.DiagnosticCategory.Error, "Identifier_expected_1003", "Identifier expected."),
        _0_expected: diag(1005, ts.DiagnosticCategory.Error, "_0_expected_1005", "'{0}' expected."),
        A_file_cannot_have_a_reference_to_itself: diag(1006, ts.DiagnosticCategory.Error, "A_file_cannot_have_a_reference_to_itself_1006", "A file cannot have a reference to itself."),
        Trailing_comma_not_allowed: diag(1009, ts.DiagnosticCategory.Error, "Trailing_comma_not_allowed_1009", "Trailing comma not allowed."),
        Asterisk_Slash_expected: diag(1010, ts.DiagnosticCategory.Error, "Asterisk_Slash_expected_1010", "'*/' expected."),
        Unexpected_token: diag(1012, ts.DiagnosticCategory.Error, "Unexpected_token_1012", "Unexpected token."),
        A_rest_parameter_must_be_last_in_a_parameter_list: diag(1014, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_last_in_a_parameter_list_1014", "A rest parameter must be last in a parameter list."),
        Parameter_cannot_have_question_mark_and_initializer: diag(1015, ts.DiagnosticCategory.Error, "Parameter_cannot_have_question_mark_and_initializer_1015", "Parameter cannot have question mark and initializer."),
        A_required_parameter_cannot_follow_an_optional_parameter: diag(1016, ts.DiagnosticCategory.Error, "A_required_parameter_cannot_follow_an_optional_parameter_1016", "A required parameter cannot follow an optional parameter."),
        An_index_signature_cannot_have_a_rest_parameter: diag(1017, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_rest_parameter_1017", "An index signature cannot have a rest parameter."),
        An_index_signature_parameter_cannot_have_an_accessibility_modifier: diag(1018, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", "An index signature parameter cannot have an accessibility modifier."),
        An_index_signature_parameter_cannot_have_a_question_mark: diag(1019, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_a_question_mark_1019", "An index signature parameter cannot have a question mark."),
        An_index_signature_parameter_cannot_have_an_initializer: diag(1020, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_initializer_1020", "An index signature parameter cannot have an initializer."),
        An_index_signature_must_have_a_type_annotation: diag(1021, ts.DiagnosticCategory.Error, "An_index_signature_must_have_a_type_annotation_1021", "An index signature must have a type annotation."),
        An_index_signature_parameter_must_have_a_type_annotation: diag(1022, ts.DiagnosticCategory.Error, "An_index_signature_parameter_must_have_a_type_annotation_1022", "An index signature parameter must have a type annotation."),
        An_index_signature_parameter_type_must_be_string_or_number: diag(1023, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_must_be_string_or_number_1023", "An index signature parameter type must be 'string' or 'number'."),
        readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: diag(1024, ts.DiagnosticCategory.Error, "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", "'readonly' modifier can only appear on a property declaration or index signature."),
        Accessibility_modifier_already_seen: diag(1028, ts.DiagnosticCategory.Error, "Accessibility_modifier_already_seen_1028", "Accessibility modifier already seen."),
        _0_modifier_must_precede_1_modifier: diag(1029, ts.DiagnosticCategory.Error, "_0_modifier_must_precede_1_modifier_1029", "'{0}' modifier must precede '{1}' modifier."),
        _0_modifier_already_seen: diag(1030, ts.DiagnosticCategory.Error, "_0_modifier_already_seen_1030", "'{0}' modifier already seen."),
        _0_modifier_cannot_appear_on_a_class_element: diag(1031, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_class_element_1031", "'{0}' modifier cannot appear on a class element."),
        super_must_be_followed_by_an_argument_list_or_member_access: diag(1034, ts.DiagnosticCategory.Error, "super_must_be_followed_by_an_argument_list_or_member_access_1034", "'super' must be followed by an argument list or member access."),
        Only_ambient_modules_can_use_quoted_names: diag(1035, ts.DiagnosticCategory.Error, "Only_ambient_modules_can_use_quoted_names_1035", "Only ambient modules can use quoted names."),
        Statements_are_not_allowed_in_ambient_contexts: diag(1036, ts.DiagnosticCategory.Error, "Statements_are_not_allowed_in_ambient_contexts_1036", "Statements are not allowed in ambient contexts."),
        A_declare_modifier_cannot_be_used_in_an_already_ambient_context: diag(1038, ts.DiagnosticCategory.Error, "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", "A 'declare' modifier cannot be used in an already ambient context."),
        Initializers_are_not_allowed_in_ambient_contexts: diag(1039, ts.DiagnosticCategory.Error, "Initializers_are_not_allowed_in_ambient_contexts_1039", "Initializers are not allowed in ambient contexts."),
        _0_modifier_cannot_be_used_in_an_ambient_context: diag(1040, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_in_an_ambient_context_1040", "'{0}' modifier cannot be used in an ambient context."),
        _0_modifier_cannot_be_used_with_a_class_declaration: diag(1041, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_class_declaration_1041", "'{0}' modifier cannot be used with a class declaration."),
        _0_modifier_cannot_be_used_here: diag(1042, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_here_1042", "'{0}' modifier cannot be used here."),
        _0_modifier_cannot_appear_on_a_data_property: diag(1043, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_data_property_1043", "'{0}' modifier cannot appear on a data property."),
        _0_modifier_cannot_appear_on_a_module_or_namespace_element: diag(1044, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", "'{0}' modifier cannot appear on a module or namespace element."),
        A_0_modifier_cannot_be_used_with_an_interface_declaration: diag(1045, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", "A '{0}' modifier cannot be used with an interface declaration."),
        A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: diag(1046, ts.DiagnosticCategory.Error, "A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046", "A 'declare' modifier is required for a top level declaration in a .d.ts file."),
        A_rest_parameter_cannot_be_optional: diag(1047, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_be_optional_1047", "A rest parameter cannot be optional."),
        A_rest_parameter_cannot_have_an_initializer: diag(1048, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_have_an_initializer_1048", "A rest parameter cannot have an initializer."),
        A_set_accessor_must_have_exactly_one_parameter: diag(1049, ts.DiagnosticCategory.Error, "A_set_accessor_must_have_exactly_one_parameter_1049", "A 'set' accessor must have exactly one parameter."),
        A_set_accessor_cannot_have_an_optional_parameter: diag(1051, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_an_optional_parameter_1051", "A 'set' accessor cannot have an optional parameter."),
        A_set_accessor_parameter_cannot_have_an_initializer: diag(1052, ts.DiagnosticCategory.Error, "A_set_accessor_parameter_cannot_have_an_initializer_1052", "A 'set' accessor parameter cannot have an initializer."),
        A_set_accessor_cannot_have_rest_parameter: diag(1053, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_rest_parameter_1053", "A 'set' accessor cannot have rest parameter."),
        A_get_accessor_cannot_have_parameters: diag(1054, ts.DiagnosticCategory.Error, "A_get_accessor_cannot_have_parameters_1054", "A 'get' accessor cannot have parameters."),
        Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value: diag(1055, ts.DiagnosticCategory.Error, "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055", "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value."),
        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: diag(1056, ts.DiagnosticCategory.Error, "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", "Accessors are only available when targeting ECMAScript 5 and higher."),
        An_async_function_or_method_must_have_a_valid_awaitable_return_type: diag(1057, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", "An async function or method must have a valid awaitable return type."),
        The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1058, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."),
        A_promise_must_have_a_then_method: diag(1059, ts.DiagnosticCategory.Error, "A_promise_must_have_a_then_method_1059", "A promise must have a 'then' method."),
        The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback: diag(1060, ts.DiagnosticCategory.Error, "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", "The first parameter of the 'then' method of a promise must be a callback."),
        Enum_member_must_have_initializer: diag(1061, ts.DiagnosticCategory.Error, "Enum_member_must_have_initializer_1061", "Enum member must have initializer."),
        Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: diag(1062, ts.DiagnosticCategory.Error, "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."),
        An_export_assignment_cannot_be_used_in_a_namespace: diag(1063, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_namespace_1063", "An export assignment cannot be used in a namespace."),
        The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type: diag(1064, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", "The return type of an async function or method must be the global Promise<T> type."),
        In_ambient_enum_declarations_member_initializer_must_be_constant_expression: diag(1066, ts.DiagnosticCategory.Error, "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", "In ambient enum declarations member initializer must be constant expression."),
        Unexpected_token_A_constructor_method_accessor_or_property_was_expected: diag(1068, ts.DiagnosticCategory.Error, "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", "Unexpected token. A constructor, method, accessor, or property was expected."),
        _0_modifier_cannot_appear_on_a_type_member: diag(1070, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_type_member_1070", "'{0}' modifier cannot appear on a type member."),
        _0_modifier_cannot_appear_on_an_index_signature: diag(1071, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_an_index_signature_1071", "'{0}' modifier cannot appear on an index signature."),
        A_0_modifier_cannot_be_used_with_an_import_declaration: diag(1079, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", "A '{0}' modifier cannot be used with an import declaration."),
        Invalid_reference_directive_syntax: diag(1084, ts.DiagnosticCategory.Error, "Invalid_reference_directive_syntax_1084", "Invalid 'reference' directive syntax."),
        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0: diag(1085, ts.DiagnosticCategory.Error, "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085", "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'."),
        An_accessor_cannot_be_declared_in_an_ambient_context: diag(1086, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_declared_in_an_ambient_context_1086", "An accessor cannot be declared in an ambient context."),
        _0_modifier_cannot_appear_on_a_constructor_declaration: diag(1089, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", "'{0}' modifier cannot appear on a constructor declaration."),
        _0_modifier_cannot_appear_on_a_parameter: diag(1090, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_parameter_1090", "'{0}' modifier cannot appear on a parameter."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: diag(1091, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", "Only a single variable declaration is allowed in a 'for...in' statement."),
        Type_parameters_cannot_appear_on_a_constructor_declaration: diag(1092, ts.DiagnosticCategory.Error, "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", "Type parameters cannot appear on a constructor declaration."),
        Type_annotation_cannot_appear_on_a_constructor_declaration: diag(1093, ts.DiagnosticCategory.Error, "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", "Type annotation cannot appear on a constructor declaration."),
        An_accessor_cannot_have_type_parameters: diag(1094, ts.DiagnosticCategory.Error, "An_accessor_cannot_have_type_parameters_1094", "An accessor cannot have type parameters."),
        A_set_accessor_cannot_have_a_return_type_annotation: diag(1095, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_a_return_type_annotation_1095", "A 'set' accessor cannot have a return type annotation."),
        An_index_signature_must_have_exactly_one_parameter: diag(1096, ts.DiagnosticCategory.Error, "An_index_signature_must_have_exactly_one_parameter_1096", "An index signature must have exactly one parameter."),
        _0_list_cannot_be_empty: diag(1097, ts.DiagnosticCategory.Error, "_0_list_cannot_be_empty_1097", "'{0}' list cannot be empty."),
        Type_parameter_list_cannot_be_empty: diag(1098, ts.DiagnosticCategory.Error, "Type_parameter_list_cannot_be_empty_1098", "Type parameter list cannot be empty."),
        Type_argument_list_cannot_be_empty: diag(1099, ts.DiagnosticCategory.Error, "Type_argument_list_cannot_be_empty_1099", "Type argument list cannot be empty."),
        Invalid_use_of_0_in_strict_mode: diag(1100, ts.DiagnosticCategory.Error, "Invalid_use_of_0_in_strict_mode_1100", "Invalid use of '{0}' in strict mode."),
        with_statements_are_not_allowed_in_strict_mode: diag(1101, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_strict_mode_1101", "'with' statements are not allowed in strict mode."),
        delete_cannot_be_called_on_an_identifier_in_strict_mode: diag(1102, ts.DiagnosticCategory.Error, "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", "'delete' cannot be called on an identifier in strict mode."),
        A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator: diag(1103, ts.DiagnosticCategory.Error, "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103", "A 'for-await-of' statement is only allowed within an async function or async generator."),
        A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: diag(1104, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", "A 'continue' statement can only be used within an enclosing iteration statement."),
        A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: diag(1105, ts.DiagnosticCategory.Error, "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", "A 'break' statement can only be used within an enclosing iteration or switch statement."),
        Jump_target_cannot_cross_function_boundary: diag(1107, ts.DiagnosticCategory.Error, "Jump_target_cannot_cross_function_boundary_1107", "Jump target cannot cross function boundary."),
        A_return_statement_can_only_be_used_within_a_function_body: diag(1108, ts.DiagnosticCategory.Error, "A_return_statement_can_only_be_used_within_a_function_body_1108", "A 'return' statement can only be used within a function body."),
        Expression_expected: diag(1109, ts.DiagnosticCategory.Error, "Expression_expected_1109", "Expression expected."),
        Type_expected: diag(1110, ts.DiagnosticCategory.Error, "Type_expected_1110", "Type expected."),
        A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: diag(1113, ts.DiagnosticCategory.Error, "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", "A 'default' clause cannot appear more than once in a 'switch' statement."),
        Duplicate_label_0: diag(1114, ts.DiagnosticCategory.Error, "Duplicate_label_0_1114", "Duplicate label '{0}'."),
        A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: diag(1115, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", "A 'continue' statement can only jump to a label of an enclosing iteration statement."),
        A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: diag(1116, ts.DiagnosticCategory.Error, "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", "A 'break' statement can only jump to a label of an enclosing statement."),
        An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: diag(1117, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", "An object literal cannot have multiple properties with the same name in strict mode."),
        An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: diag(1118, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", "An object literal cannot have multiple get/set accessors with the same name."),
        An_object_literal_cannot_have_property_and_accessor_with_the_same_name: diag(1119, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", "An object literal cannot have property and accessor with the same name."),
        An_export_assignment_cannot_have_modifiers: diag(1120, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_have_modifiers_1120", "An export assignment cannot have modifiers."),
        Octal_literals_are_not_allowed_in_strict_mode: diag(1121, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_strict_mode_1121", "Octal literals are not allowed in strict mode."),
        A_tuple_type_element_list_cannot_be_empty: diag(1122, ts.DiagnosticCategory.Error, "A_tuple_type_element_list_cannot_be_empty_1122", "A tuple type element list cannot be empty."),
        Variable_declaration_list_cannot_be_empty: diag(1123, ts.DiagnosticCategory.Error, "Variable_declaration_list_cannot_be_empty_1123", "Variable declaration list cannot be empty."),
        Digit_expected: diag(1124, ts.DiagnosticCategory.Error, "Digit_expected_1124", "Digit expected."),
        Hexadecimal_digit_expected: diag(1125, ts.DiagnosticCategory.Error, "Hexadecimal_digit_expected_1125", "Hexadecimal digit expected."),
        Unexpected_end_of_text: diag(1126, ts.DiagnosticCategory.Error, "Unexpected_end_of_text_1126", "Unexpected end of text."),
        Invalid_character: diag(1127, ts.DiagnosticCategory.Error, "Invalid_character_1127", "Invalid character."),
        Declaration_or_statement_expected: diag(1128, ts.DiagnosticCategory.Error, "Declaration_or_statement_expected_1128", "Declaration or statement expected."),
        Statement_expected: diag(1129, ts.DiagnosticCategory.Error, "Statement_expected_1129", "Statement expected."),
        case_or_default_expected: diag(1130, ts.DiagnosticCategory.Error, "case_or_default_expected_1130", "'case' or 'default' expected."),
        Property_or_signature_expected: diag(1131, ts.DiagnosticCategory.Error, "Property_or_signature_expected_1131", "Property or signature expected."),
        Enum_member_expected: diag(1132, ts.DiagnosticCategory.Error, "Enum_member_expected_1132", "Enum member expected."),
        Variable_declaration_expected: diag(1134, ts.DiagnosticCategory.Error, "Variable_declaration_expected_1134", "Variable declaration expected."),
        Argument_expression_expected: diag(1135, ts.DiagnosticCategory.Error, "Argument_expression_expected_1135", "Argument expression expected."),
        Property_assignment_expected: diag(1136, ts.DiagnosticCategory.Error, "Property_assignment_expected_1136", "Property assignment expected."),
        Expression_or_comma_expected: diag(1137, ts.DiagnosticCategory.Error, "Expression_or_comma_expected_1137", "Expression or comma expected."),
        Parameter_declaration_expected: diag(1138, ts.DiagnosticCategory.Error, "Parameter_declaration_expected_1138", "Parameter declaration expected."),
        Type_parameter_declaration_expected: diag(1139, ts.DiagnosticCategory.Error, "Type_parameter_declaration_expected_1139", "Type parameter declaration expected."),
        Type_argument_expected: diag(1140, ts.DiagnosticCategory.Error, "Type_argument_expected_1140", "Type argument expected."),
        String_literal_expected: diag(1141, ts.DiagnosticCategory.Error, "String_literal_expected_1141", "String literal expected."),
        Line_break_not_permitted_here: diag(1142, ts.DiagnosticCategory.Error, "Line_break_not_permitted_here_1142", "Line break not permitted here."),
        or_expected: diag(1144, ts.DiagnosticCategory.Error, "or_expected_1144", "'{' or ';' expected."),
        Declaration_expected: diag(1146, ts.DiagnosticCategory.Error, "Declaration_expected_1146", "Declaration expected."),
        Import_declarations_in_a_namespace_cannot_reference_a_module: diag(1147, ts.DiagnosticCategory.Error, "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", "Import declarations in a namespace cannot reference a module."),
        Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: diag(1148, ts.DiagnosticCategory.Error, "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", "Cannot use imports, exports, or module augmentations when '--module' is 'none'."),
        File_name_0_differs_from_already_included_file_name_1_only_in_casing: diag(1149, ts.DiagnosticCategory.Error, "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", "File name '{0}' differs from already included file name '{1}' only in casing."),
        new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: diag(1150, ts.DiagnosticCategory.Error, "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead."),
        const_declarations_must_be_initialized: diag(1155, ts.DiagnosticCategory.Error, "const_declarations_must_be_initialized_1155", "'const' declarations must be initialized."),
        const_declarations_can_only_be_declared_inside_a_block: diag(1156, ts.DiagnosticCategory.Error, "const_declarations_can_only_be_declared_inside_a_block_1156", "'const' declarations can only be declared inside a block."),
        let_declarations_can_only_be_declared_inside_a_block: diag(1157, ts.DiagnosticCategory.Error, "let_declarations_can_only_be_declared_inside_a_block_1157", "'let' declarations can only be declared inside a block."),
        Unterminated_template_literal: diag(1160, ts.DiagnosticCategory.Error, "Unterminated_template_literal_1160", "Unterminated template literal."),
        Unterminated_regular_expression_literal: diag(1161, ts.DiagnosticCategory.Error, "Unterminated_regular_expression_literal_1161", "Unterminated regular expression literal."),
        An_object_member_cannot_be_declared_optional: diag(1162, ts.DiagnosticCategory.Error, "An_object_member_cannot_be_declared_optional_1162", "An object member cannot be declared optional."),
        A_yield_expression_is_only_allowed_in_a_generator_body: diag(1163, ts.DiagnosticCategory.Error, "A_yield_expression_is_only_allowed_in_a_generator_body_1163", "A 'yield' expression is only allowed in a generator body."),
        Computed_property_names_are_not_allowed_in_enums: diag(1164, ts.DiagnosticCategory.Error, "Computed_property_names_are_not_allowed_in_enums_1164", "Computed property names are not allowed in enums."),
        A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: diag(1165, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol_1165", "A computed property name in an ambient context must directly refer to a built-in symbol."),
        A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: diag(1166, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol_1166", "A computed property name in a class property declaration must directly refer to a built-in symbol."),
        A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol: diag(1168, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol_1168", "A computed property name in a method overload must directly refer to a built-in symbol."),
        A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol: diag(1169, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol_1169", "A computed property name in an interface must directly refer to a built-in symbol."),
        A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol: diag(1170, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol_1170", "A computed property name in a type literal must directly refer to a built-in symbol."),
        A_comma_expression_is_not_allowed_in_a_computed_property_name: diag(1171, ts.DiagnosticCategory.Error, "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", "A comma expression is not allowed in a computed property name."),
        extends_clause_already_seen: diag(1172, ts.DiagnosticCategory.Error, "extends_clause_already_seen_1172", "'extends' clause already seen."),
        extends_clause_must_precede_implements_clause: diag(1173, ts.DiagnosticCategory.Error, "extends_clause_must_precede_implements_clause_1173", "'extends' clause must precede 'implements' clause."),
        Classes_can_only_extend_a_single_class: diag(1174, ts.DiagnosticCategory.Error, "Classes_can_only_extend_a_single_class_1174", "Classes can only extend a single class."),
        implements_clause_already_seen: diag(1175, ts.DiagnosticCategory.Error, "implements_clause_already_seen_1175", "'implements' clause already seen."),
        Interface_declaration_cannot_have_implements_clause: diag(1176, ts.DiagnosticCategory.Error, "Interface_declaration_cannot_have_implements_clause_1176", "Interface declaration cannot have 'implements' clause."),
        Binary_digit_expected: diag(1177, ts.DiagnosticCategory.Error, "Binary_digit_expected_1177", "Binary digit expected."),
        Octal_digit_expected: diag(1178, ts.DiagnosticCategory.Error, "Octal_digit_expected_1178", "Octal digit expected."),
        Unexpected_token_expected: diag(1179, ts.DiagnosticCategory.Error, "Unexpected_token_expected_1179", "Unexpected token. '{' expected."),
        Property_destructuring_pattern_expected: diag(1180, ts.DiagnosticCategory.Error, "Property_destructuring_pattern_expected_1180", "Property destructuring pattern expected."),
        Array_element_destructuring_pattern_expected: diag(1181, ts.DiagnosticCategory.Error, "Array_element_destructuring_pattern_expected_1181", "Array element destructuring pattern expected."),
        A_destructuring_declaration_must_have_an_initializer: diag(1182, ts.DiagnosticCategory.Error, "A_destructuring_declaration_must_have_an_initializer_1182", "A destructuring declaration must have an initializer."),
        An_implementation_cannot_be_declared_in_ambient_contexts: diag(1183, ts.DiagnosticCategory.Error, "An_implementation_cannot_be_declared_in_ambient_contexts_1183", "An implementation cannot be declared in ambient contexts."),
        Modifiers_cannot_appear_here: diag(1184, ts.DiagnosticCategory.Error, "Modifiers_cannot_appear_here_1184", "Modifiers cannot appear here."),
        Merge_conflict_marker_encountered: diag(1185, ts.DiagnosticCategory.Error, "Merge_conflict_marker_encountered_1185", "Merge conflict marker encountered."),
        A_rest_element_cannot_have_an_initializer: diag(1186, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_an_initializer_1186", "A rest element cannot have an initializer."),
        A_parameter_property_may_not_be_declared_using_a_binding_pattern: diag(1187, ts.DiagnosticCategory.Error, "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", "A parameter property may not be declared using a binding pattern."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: diag(1188, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", "Only a single variable declaration is allowed in a 'for...of' statement."),
        The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: diag(1189, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", "The variable declaration of a 'for...in' statement cannot have an initializer."),
        The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: diag(1190, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", "The variable declaration of a 'for...of' statement cannot have an initializer."),
        An_import_declaration_cannot_have_modifiers: diag(1191, ts.DiagnosticCategory.Error, "An_import_declaration_cannot_have_modifiers_1191", "An import declaration cannot have modifiers."),
        Module_0_has_no_default_export: diag(1192, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_1192", "Module '{0}' has no default export."),
        An_export_declaration_cannot_have_modifiers: diag(1193, ts.DiagnosticCategory.Error, "An_export_declaration_cannot_have_modifiers_1193", "An export declaration cannot have modifiers."),
        Export_declarations_are_not_permitted_in_a_namespace: diag(1194, ts.DiagnosticCategory.Error, "Export_declarations_are_not_permitted_in_a_namespace_1194", "Export declarations are not permitted in a namespace."),
        Catch_clause_variable_cannot_have_a_type_annotation: diag(1196, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_a_type_annotation_1196", "Catch clause variable cannot have a type annotation."),
        Catch_clause_variable_cannot_have_an_initializer: diag(1197, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_an_initializer_1197", "Catch clause variable cannot have an initializer."),
        An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: diag(1198, ts.DiagnosticCategory.Error, "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."),
        Unterminated_Unicode_escape_sequence: diag(1199, ts.DiagnosticCategory.Error, "Unterminated_Unicode_escape_sequence_1199", "Unterminated Unicode escape sequence."),
        Line_terminator_not_permitted_before_arrow: diag(1200, ts.DiagnosticCategory.Error, "Line_terminator_not_permitted_before_arrow_1200", "Line terminator not permitted before arrow."),
        Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: diag(1202, ts.DiagnosticCategory.Error, "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."),
        Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead: diag(1203, ts.DiagnosticCategory.Error, "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."),
        Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided: diag(1205, ts.DiagnosticCategory.Error, "Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205", "Cannot re-export a type when the '--isolatedModules' flag is provided."),
        Decorators_are_not_valid_here: diag(1206, ts.DiagnosticCategory.Error, "Decorators_are_not_valid_here_1206", "Decorators are not valid here."),
        Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: diag(1207, ts.DiagnosticCategory.Error, "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", "Decorators cannot be applied to multiple get/set accessors of the same name."),
        Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: diag(1208, ts.DiagnosticCategory.Error, "Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided_1208", "Cannot compile namespaces when the '--isolatedModules' flag is provided."),
        Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: diag(1209, ts.DiagnosticCategory.Error, "Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided_1209", "Ambient const enums are not allowed when the '--isolatedModules' flag is provided."),
        Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: diag(1210, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", "Invalid use of '{0}'. Class definitions are automatically in strict mode."),
        A_class_declaration_without_the_default_modifier_must_have_a_name: diag(1211, ts.DiagnosticCategory.Error, "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", "A class declaration without the 'default' modifier must have a name."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode: diag(1212, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", "Identifier expected. '{0}' is a reserved word in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: diag(1213, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: diag(1214, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."),
        Invalid_use_of_0_Modules_are_automatically_in_strict_mode: diag(1215, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", "Invalid use of '{0}'. Modules are automatically in strict mode."),
        Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules: diag(1216, ts.DiagnosticCategory.Error, "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."),
        Export_assignment_is_not_supported_when_module_flag_is_system: diag(1218, ts.DiagnosticCategory.Error, "Export_assignment_is_not_supported_when_module_flag_is_system_1218", "Export assignment is not supported when '--module' flag is 'system'."),
        Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning: diag(1219, ts.DiagnosticCategory.Error, "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning."),
        Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher: diag(1220, ts.DiagnosticCategory.Error, "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", "Generators are only available when targeting ECMAScript 2015 or higher."),
        Generators_are_not_allowed_in_an_ambient_context: diag(1221, ts.DiagnosticCategory.Error, "Generators_are_not_allowed_in_an_ambient_context_1221", "Generators are not allowed in an ambient context."),
        An_overload_signature_cannot_be_declared_as_a_generator: diag(1222, ts.DiagnosticCategory.Error, "An_overload_signature_cannot_be_declared_as_a_generator_1222", "An overload signature cannot be declared as a generator."),
        _0_tag_already_specified: diag(1223, ts.DiagnosticCategory.Error, "_0_tag_already_specified_1223", "'{0}' tag already specified."),
        Signature_0_must_be_a_type_predicate: diag(1224, ts.DiagnosticCategory.Error, "Signature_0_must_be_a_type_predicate_1224", "Signature '{0}' must be a type predicate."),
        Cannot_find_parameter_0: diag(1225, ts.DiagnosticCategory.Error, "Cannot_find_parameter_0_1225", "Cannot find parameter '{0}'."),
        Type_predicate_0_is_not_assignable_to_1: diag(1226, ts.DiagnosticCategory.Error, "Type_predicate_0_is_not_assignable_to_1_1226", "Type predicate '{0}' is not assignable to '{1}'."),
        Parameter_0_is_not_in_the_same_position_as_parameter_1: diag(1227, ts.DiagnosticCategory.Error, "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", "Parameter '{0}' is not in the same position as parameter '{1}'."),
        A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: diag(1228, ts.DiagnosticCategory.Error, "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", "A type predicate is only allowed in return type position for functions and methods."),
        A_type_predicate_cannot_reference_a_rest_parameter: diag(1229, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_a_rest_parameter_1229", "A type predicate cannot reference a rest parameter."),
        A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: diag(1230, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", "A type predicate cannot reference element '{0}' in a binding pattern."),
        An_export_assignment_can_only_be_used_in_a_module: diag(1231, ts.DiagnosticCategory.Error, "An_export_assignment_can_only_be_used_in_a_module_1231", "An export assignment can only be used in a module."),
        An_import_declaration_can_only_be_used_in_a_namespace_or_module: diag(1232, ts.DiagnosticCategory.Error, "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", "An import declaration can only be used in a namespace or module."),
        An_export_declaration_can_only_be_used_in_a_module: diag(1233, ts.DiagnosticCategory.Error, "An_export_declaration_can_only_be_used_in_a_module_1233", "An export declaration can only be used in a module."),
        An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: diag(1234, ts.DiagnosticCategory.Error, "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", "An ambient module declaration is only allowed at the top level in a file."),
        A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: diag(1235, ts.DiagnosticCategory.Error, "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", "A namespace declaration is only allowed in a namespace or module."),
        The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: diag(1236, ts.DiagnosticCategory.Error, "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", "The return type of a property decorator function must be either 'void' or 'any'."),
        The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: diag(1237, ts.DiagnosticCategory.Error, "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", "The return type of a parameter decorator function must be either 'void' or 'any'."),
        Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: diag(1238, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", "Unable to resolve signature of class decorator when called as an expression."),
        Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: diag(1239, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", "Unable to resolve signature of parameter decorator when called as an expression."),
        Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: diag(1240, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", "Unable to resolve signature of property decorator when called as an expression."),
        Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: diag(1241, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", "Unable to resolve signature of method decorator when called as an expression."),
        abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: diag(1242, ts.DiagnosticCategory.Error, "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", "'abstract' modifier can only appear on a class, method, or property declaration."),
        _0_modifier_cannot_be_used_with_1_modifier: diag(1243, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_1_modifier_1243", "'{0}' modifier cannot be used with '{1}' modifier."),
        Abstract_methods_can_only_appear_within_an_abstract_class: diag(1244, ts.DiagnosticCategory.Error, "Abstract_methods_can_only_appear_within_an_abstract_class_1244", "Abstract methods can only appear within an abstract class."),
        Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: diag(1245, ts.DiagnosticCategory.Error, "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", "Method '{0}' cannot have an implementation because it is marked abstract."),
        An_interface_property_cannot_have_an_initializer: diag(1246, ts.DiagnosticCategory.Error, "An_interface_property_cannot_have_an_initializer_1246", "An interface property cannot have an initializer."),
        A_type_literal_property_cannot_have_an_initializer: diag(1247, ts.DiagnosticCategory.Error, "A_type_literal_property_cannot_have_an_initializer_1247", "A type literal property cannot have an initializer."),
        A_class_member_cannot_have_the_0_keyword: diag(1248, ts.DiagnosticCategory.Error, "A_class_member_cannot_have_the_0_keyword_1248", "A class member cannot have the '{0}' keyword."),
        A_decorator_can_only_decorate_a_method_implementation_not_an_overload: diag(1249, ts.DiagnosticCategory.Error, "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", "A decorator can only decorate a method implementation, not an overload."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5: diag(1250, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode: diag(1251, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode: diag(1252, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode."),
        _0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag: diag(1253, ts.DiagnosticCategory.Error, "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", "'{0}' tag cannot be used independently as a top level JSDoc tag."),
        A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal: diag(1254, ts.DiagnosticCategory.Error, "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254", "A 'const' initializer in an ambient context must be a string or numeric literal."),
        with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."),
        await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."),
        can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."),
        The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."),
        Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."),
        Global_module_exports_may_only_appear_in_declaration_files: diag(1315, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_declaration_files_1315", "Global module exports may only appear in declaration files."),
        Global_module_exports_may_only_appear_at_top_level: diag(1316, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_at_top_level_1316", "Global module exports may only appear at top level."),
        A_parameter_property_cannot_be_declared_using_a_rest_parameter: diag(1317, ts.DiagnosticCategory.Error, "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", "A parameter property cannot be declared using a rest parameter."),
        An_abstract_accessor_cannot_have_an_implementation: diag(1318, ts.DiagnosticCategory.Error, "An_abstract_accessor_cannot_have_an_implementation_1318", "An abstract accessor cannot have an implementation."),
        A_default_export_can_only_be_used_in_an_ECMAScript_style_module: diag(1319, ts.DiagnosticCategory.Error, "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", "A default export can only be used in an ECMAScript-style module."),
        Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1320, ts.DiagnosticCategory.Error, "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1321, ts.DiagnosticCategory.Error, "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1322, ts.DiagnosticCategory.Error, "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."),
        Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules: diag(1323, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules_1323", "Dynamic import cannot be used when targeting ECMAScript 2015 modules."),
        Dynamic_import_must_have_one_specifier_as_an_argument: diag(1324, ts.DiagnosticCategory.Error, "Dynamic_import_must_have_one_specifier_as_an_argument_1324", "Dynamic import must have one specifier as an argument."),
        Specifier_of_dynamic_import_cannot_be_spread_element: diag(1325, ts.DiagnosticCategory.Error, "Specifier_of_dynamic_import_cannot_be_spread_element_1325", "Specifier of dynamic import cannot be spread element."),
        Dynamic_import_cannot_have_type_arguments: diag(1326, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_have_type_arguments_1326", "Dynamic import cannot have type arguments"),
        String_literal_with_double_quotes_expected: diag(1327, ts.DiagnosticCategory.Error, "String_literal_with_double_quotes_expected_1327", "String literal with double quotes expected."),
        Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal: diag(1328, ts.DiagnosticCategory.Error, "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."),
        _0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0: diag(1329, ts.DiagnosticCategory.Error, "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"),
        Duplicate_identifier_0: diag(2300, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_2300", "Duplicate identifier '{0}'."),
        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: diag(2301, ts.DiagnosticCategory.Error, "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."),
        Static_members_cannot_reference_class_type_parameters: diag(2302, ts.DiagnosticCategory.Error, "Static_members_cannot_reference_class_type_parameters_2302", "Static members cannot reference class type parameters."),
        Circular_definition_of_import_alias_0: diag(2303, ts.DiagnosticCategory.Error, "Circular_definition_of_import_alias_0_2303", "Circular definition of import alias '{0}'."),
        Cannot_find_name_0: diag(2304, ts.DiagnosticCategory.Error, "Cannot_find_name_0_2304", "Cannot find name '{0}'."),
        Module_0_has_no_exported_member_1: diag(2305, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_2305", "Module '{0}' has no exported member '{1}'."),
        File_0_is_not_a_module: diag(2306, ts.DiagnosticCategory.Error, "File_0_is_not_a_module_2306", "File '{0}' is not a module."),
        Cannot_find_module_0: diag(2307, ts.DiagnosticCategory.Error, "Cannot_find_module_0_2307", "Cannot find module '{0}'."),
        Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: diag(2308, ts.DiagnosticCategory.Error, "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."),
        An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: diag(2309, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", "An export assignment cannot be used in a module with other exported elements."),
        Type_0_recursively_references_itself_as_a_base_type: diag(2310, ts.DiagnosticCategory.Error, "Type_0_recursively_references_itself_as_a_base_type_2310", "Type '{0}' recursively references itself as a base type."),
        A_class_may_only_extend_another_class: diag(2311, ts.DiagnosticCategory.Error, "A_class_may_only_extend_another_class_2311", "A class may only extend another class."),
        An_interface_may_only_extend_a_class_or_another_interface: diag(2312, ts.DiagnosticCategory.Error, "An_interface_may_only_extend_a_class_or_another_interface_2312", "An interface may only extend a class or another interface."),
        Type_parameter_0_has_a_circular_constraint: diag(2313, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_constraint_2313", "Type parameter '{0}' has a circular constraint."),
        Generic_type_0_requires_1_type_argument_s: diag(2314, ts.DiagnosticCategory.Error, "Generic_type_0_requires_1_type_argument_s_2314", "Generic type '{0}' requires {1} type argument(s)."),
        Type_0_is_not_generic: diag(2315, ts.DiagnosticCategory.Error, "Type_0_is_not_generic_2315", "Type '{0}' is not generic."),
        Global_type_0_must_be_a_class_or_interface_type: diag(2316, ts.DiagnosticCategory.Error, "Global_type_0_must_be_a_class_or_interface_type_2316", "Global type '{0}' must be a class or interface type."),
        Global_type_0_must_have_1_type_parameter_s: diag(2317, ts.DiagnosticCategory.Error, "Global_type_0_must_have_1_type_parameter_s_2317", "Global type '{0}' must have {1} type parameter(s)."),
        Cannot_find_global_type_0: diag(2318, ts.DiagnosticCategory.Error, "Cannot_find_global_type_0_2318", "Cannot find global type '{0}'."),
        Named_property_0_of_types_1_and_2_are_not_identical: diag(2319, ts.DiagnosticCategory.Error, "Named_property_0_of_types_1_and_2_are_not_identical_2319", "Named property '{0}' of types '{1}' and '{2}' are not identical."),
        Interface_0_cannot_simultaneously_extend_types_1_and_2: diag(2320, ts.DiagnosticCategory.Error, "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."),
        Excessive_stack_depth_comparing_types_0_and_1: diag(2321, ts.DiagnosticCategory.Error, "Excessive_stack_depth_comparing_types_0_and_1_2321", "Excessive stack depth comparing types '{0}' and '{1}'."),
        Type_0_is_not_assignable_to_type_1: diag(2322, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_2322", "Type '{0}' is not assignable to type '{1}'."),
        Cannot_redeclare_exported_variable_0: diag(2323, ts.DiagnosticCategory.Error, "Cannot_redeclare_exported_variable_0_2323", "Cannot redeclare exported variable '{0}'."),
        Property_0_is_missing_in_type_1: diag(2324, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_2324", "Property '{0}' is missing in type '{1}'."),
        Property_0_is_private_in_type_1_but_not_in_type_2: diag(2325, ts.DiagnosticCategory.Error, "Property_0_is_private_in_type_1_but_not_in_type_2_2325", "Property '{0}' is private in type '{1}' but not in type '{2}'."),
        Types_of_property_0_are_incompatible: diag(2326, ts.DiagnosticCategory.Error, "Types_of_property_0_are_incompatible_2326", "Types of property '{0}' are incompatible."),
        Property_0_is_optional_in_type_1_but_required_in_type_2: diag(2327, ts.DiagnosticCategory.Error, "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", "Property '{0}' is optional in type '{1}' but required in type '{2}'."),
        Types_of_parameters_0_and_1_are_incompatible: diag(2328, ts.DiagnosticCategory.Error, "Types_of_parameters_0_and_1_are_incompatible_2328", "Types of parameters '{0}' and '{1}' are incompatible."),
        Index_signature_is_missing_in_type_0: diag(2329, ts.DiagnosticCategory.Error, "Index_signature_is_missing_in_type_0_2329", "Index signature is missing in type '{0}'."),
        Index_signatures_are_incompatible: diag(2330, ts.DiagnosticCategory.Error, "Index_signatures_are_incompatible_2330", "Index signatures are incompatible."),
        this_cannot_be_referenced_in_a_module_or_namespace_body: diag(2331, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", "'this' cannot be referenced in a module or namespace body."),
        this_cannot_be_referenced_in_current_location: diag(2332, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_current_location_2332", "'this' cannot be referenced in current location."),
        this_cannot_be_referenced_in_constructor_arguments: diag(2333, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_constructor_arguments_2333", "'this' cannot be referenced in constructor arguments."),
        this_cannot_be_referenced_in_a_static_property_initializer: diag(2334, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_static_property_initializer_2334", "'this' cannot be referenced in a static property initializer."),
        super_can_only_be_referenced_in_a_derived_class: diag(2335, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_a_derived_class_2335", "'super' can only be referenced in a derived class."),
        super_cannot_be_referenced_in_constructor_arguments: diag(2336, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_constructor_arguments_2336", "'super' cannot be referenced in constructor arguments."),
        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: diag(2337, ts.DiagnosticCategory.Error, "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", "Super calls are not permitted outside constructors or in nested functions inside constructors."),
        super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: diag(2338, ts.DiagnosticCategory.Error, "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."),
        Property_0_does_not_exist_on_type_1: diag(2339, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_2339", "Property '{0}' does not exist on type '{1}'."),
        Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: diag(2340, ts.DiagnosticCategory.Error, "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", "Only public and protected methods of the base class are accessible via the 'super' keyword."),
        Property_0_is_private_and_only_accessible_within_class_1: diag(2341, ts.DiagnosticCategory.Error, "Property_0_is_private_and_only_accessible_within_class_1_2341", "Property '{0}' is private and only accessible within class '{1}'."),
        An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: diag(2342, ts.DiagnosticCategory.Error, "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'."),
        This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1: diag(2343, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343", "This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'."),
        Type_0_does_not_satisfy_the_constraint_1: diag(2344, ts.DiagnosticCategory.Error, "Type_0_does_not_satisfy_the_constraint_1_2344", "Type '{0}' does not satisfy the constraint '{1}'."),
        Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: diag(2345, ts.DiagnosticCategory.Error, "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", "Argument of type '{0}' is not assignable to parameter of type '{1}'."),
        Call_target_does_not_contain_any_signatures: diag(2346, ts.DiagnosticCategory.Error, "Call_target_does_not_contain_any_signatures_2346", "Call target does not contain any signatures."),
        Untyped_function_calls_may_not_accept_type_arguments: diag(2347, ts.DiagnosticCategory.Error, "Untyped_function_calls_may_not_accept_type_arguments_2347", "Untyped function calls may not accept type arguments."),
        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: diag(2348, ts.DiagnosticCategory.Error, "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", "Value of type '{0}' is not callable. Did you mean to include 'new'?"),
        Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures: diag(2349, ts.DiagnosticCategory.Error, "Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatur_2349", "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures."),
        Only_a_void_function_can_be_called_with_the_new_keyword: diag(2350, ts.DiagnosticCategory.Error, "Only_a_void_function_can_be_called_with_the_new_keyword_2350", "Only a void function can be called with the 'new' keyword."),
        Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: diag(2351, ts.DiagnosticCategory.Error, "Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature_2351", "Cannot use 'new' with an expression whose type lacks a call or construct signature."),
        Type_0_cannot_be_converted_to_type_1: diag(2352, ts.DiagnosticCategory.Error, "Type_0_cannot_be_converted_to_type_1_2352", "Type '{0}' cannot be converted to type '{1}'."),
        Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: diag(2353, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."),
        This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found: diag(2354, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", "This syntax requires an imported helper but module '{0}' cannot be found."),
        A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: diag(2355, ts.DiagnosticCategory.Error, "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", "A function whose declared type is neither 'void' nor 'any' must return a value."),
        An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: diag(2356, ts.DiagnosticCategory.Error, "An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356", "An arithmetic operand must be of type 'any', 'number' or an enum type."),
        The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access: diag(2357, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", "The operand of an increment or decrement operator must be a variable or a property access."),
        The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2358, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."),
        The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: diag(2359, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type."),
        The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: diag(2360, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'."),
        The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2361, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter."),
        The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: diag(2362, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362", "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type."),
        The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: diag(2363, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363", "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type."),
        The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: diag(2364, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", "The left-hand side of an assignment expression must be a variable or a property access."),
        Operator_0_cannot_be_applied_to_types_1_and_2: diag(2365, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_types_1_and_2_2365", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."),
        Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: diag(2366, ts.DiagnosticCategory.Error, "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", "Function lacks ending return statement and return type does not include 'undefined'."),
        Type_parameter_name_cannot_be_0: diag(2368, ts.DiagnosticCategory.Error, "Type_parameter_name_cannot_be_0_2368", "Type parameter name cannot be '{0}'."),
        A_parameter_property_is_only_allowed_in_a_constructor_implementation: diag(2369, ts.DiagnosticCategory.Error, "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", "A parameter property is only allowed in a constructor implementation."),
        A_rest_parameter_must_be_of_an_array_type: diag(2370, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_of_an_array_type_2370", "A rest parameter must be of an array type."),
        A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: diag(2371, ts.DiagnosticCategory.Error, "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", "A parameter initializer is only allowed in a function or constructor implementation."),
        Parameter_0_cannot_be_referenced_in_its_initializer: diag(2372, ts.DiagnosticCategory.Error, "Parameter_0_cannot_be_referenced_in_its_initializer_2372", "Parameter '{0}' cannot be referenced in its initializer."),
        Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: diag(2373, ts.DiagnosticCategory.Error, "Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it_2373", "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it."),
        Duplicate_string_index_signature: diag(2374, ts.DiagnosticCategory.Error, "Duplicate_string_index_signature_2374", "Duplicate string index signature."),
        Duplicate_number_index_signature: diag(2375, ts.DiagnosticCategory.Error, "Duplicate_number_index_signature_2375", "Duplicate number index signature."),
        A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: diag(2376, ts.DiagnosticCategory.Error, "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties."),
        Constructors_for_derived_classes_must_contain_a_super_call: diag(2377, ts.DiagnosticCategory.Error, "Constructors_for_derived_classes_must_contain_a_super_call_2377", "Constructors for derived classes must contain a 'super' call."),
        A_get_accessor_must_return_a_value: diag(2378, ts.DiagnosticCategory.Error, "A_get_accessor_must_return_a_value_2378", "A 'get' accessor must return a value."),
        Getter_and_setter_accessors_do_not_agree_in_visibility: diag(2379, ts.DiagnosticCategory.Error, "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", "Getter and setter accessors do not agree in visibility."),
        get_and_set_accessor_must_have_the_same_type: diag(2380, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_type_2380", "'get' and 'set' accessor must have the same type."),
        A_signature_with_an_implementation_cannot_use_a_string_literal_type: diag(2381, ts.DiagnosticCategory.Error, "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", "A signature with an implementation cannot use a string literal type."),
        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: diag(2382, ts.DiagnosticCategory.Error, "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", "Specialized overload signature is not assignable to any non-specialized signature."),
        Overload_signatures_must_all_be_exported_or_non_exported: diag(2383, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_exported_or_non_exported_2383", "Overload signatures must all be exported or non-exported."),
        Overload_signatures_must_all_be_ambient_or_non_ambient: diag(2384, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", "Overload signatures must all be ambient or non-ambient."),
        Overload_signatures_must_all_be_public_private_or_protected: diag(2385, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_public_private_or_protected_2385", "Overload signatures must all be public, private or protected."),
        Overload_signatures_must_all_be_optional_or_required: diag(2386, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_optional_or_required_2386", "Overload signatures must all be optional or required."),
        Function_overload_must_be_static: diag(2387, ts.DiagnosticCategory.Error, "Function_overload_must_be_static_2387", "Function overload must be static."),
        Function_overload_must_not_be_static: diag(2388, ts.DiagnosticCategory.Error, "Function_overload_must_not_be_static_2388", "Function overload must not be static."),
        Function_implementation_name_must_be_0: diag(2389, ts.DiagnosticCategory.Error, "Function_implementation_name_must_be_0_2389", "Function implementation name must be '{0}'."),
        Constructor_implementation_is_missing: diag(2390, ts.DiagnosticCategory.Error, "Constructor_implementation_is_missing_2390", "Constructor implementation is missing."),
        Function_implementation_is_missing_or_not_immediately_following_the_declaration: diag(2391, ts.DiagnosticCategory.Error, "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", "Function implementation is missing or not immediately following the declaration."),
        Multiple_constructor_implementations_are_not_allowed: diag(2392, ts.DiagnosticCategory.Error, "Multiple_constructor_implementations_are_not_allowed_2392", "Multiple constructor implementations are not allowed."),
        Duplicate_function_implementation: diag(2393, ts.DiagnosticCategory.Error, "Duplicate_function_implementation_2393", "Duplicate function implementation."),
        Overload_signature_is_not_compatible_with_function_implementation: diag(2394, ts.DiagnosticCategory.Error, "Overload_signature_is_not_compatible_with_function_implementation_2394", "Overload signature is not compatible with function implementation."),
        Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: diag(2395, ts.DiagnosticCategory.Error, "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", "Individual declarations in merged declaration '{0}' must be all exported or all local."),
        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: diag(2396, ts.DiagnosticCategory.Error, "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."),
        Declaration_name_conflicts_with_built_in_global_identifier_0: diag(2397, ts.DiagnosticCategory.Error, "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", "Declaration name conflicts with built-in global identifier '{0}'."),
        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: diag(2399, ts.DiagnosticCategory.Error, "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."),
        Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: diag(2400, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."),
        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: diag(2401, ts.DiagnosticCategory.Error, "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference."),
        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: diag(2402, ts.DiagnosticCategory.Error, "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", "Expression resolves to '_super' that compiler uses to capture base class reference."),
        Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: diag(2403, ts.DiagnosticCategory.Error, "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'."),
        The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: diag(2404, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", "The left-hand side of a 'for...in' statement cannot use a type annotation."),
        The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: diag(2405, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."),
        The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access: diag(2406, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", "The left-hand side of a 'for...in' statement must be a variable or a property access."),
        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2407, ts.DiagnosticCategory.Error, "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_2407", "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter."),
        Setters_cannot_return_a_value: diag(2408, ts.DiagnosticCategory.Error, "Setters_cannot_return_a_value_2408", "Setters cannot return a value."),
        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: diag(2409, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", "Return type of constructor signature must be assignable to the instance type of the class."),
        The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any: diag(2410, ts.DiagnosticCategory.Error, "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."),
        Property_0_of_type_1_is_not_assignable_to_string_index_type_2: diag(2411, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", "Property '{0}' of type '{1}' is not assignable to string index type '{2}'."),
        Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: diag(2412, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'."),
        Numeric_index_type_0_is_not_assignable_to_string_index_type_1: diag(2413, ts.DiagnosticCategory.Error, "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", "Numeric index type '{0}' is not assignable to string index type '{1}'."),
        Class_name_cannot_be_0: diag(2414, ts.DiagnosticCategory.Error, "Class_name_cannot_be_0_2414", "Class name cannot be '{0}'."),
        Class_0_incorrectly_extends_base_class_1: diag(2415, ts.DiagnosticCategory.Error, "Class_0_incorrectly_extends_base_class_1_2415", "Class '{0}' incorrectly extends base class '{1}'."),
        Class_static_side_0_incorrectly_extends_base_class_static_side_1: diag(2417, ts.DiagnosticCategory.Error, "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", "Class static side '{0}' incorrectly extends base class static side '{1}'."),
        Class_0_incorrectly_implements_interface_1: diag(2420, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_interface_1_2420", "Class '{0}' incorrectly implements interface '{1}'."),
        A_class_may_only_implement_another_class_or_interface: diag(2422, ts.DiagnosticCategory.Error, "A_class_may_only_implement_another_class_or_interface_2422", "A class may only implement another class or interface."),
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: diag(2423, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."),
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: diag(2424, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_proper_2424", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property."),
        Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2425, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."),
        Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2426, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."),
        Interface_name_cannot_be_0: diag(2427, ts.DiagnosticCategory.Error, "Interface_name_cannot_be_0_2427", "Interface name cannot be '{0}'."),
        All_declarations_of_0_must_have_identical_type_parameters: diag(2428, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_type_parameters_2428", "All declarations of '{0}' must have identical type parameters."),
        Interface_0_incorrectly_extends_interface_1: diag(2430, ts.DiagnosticCategory.Error, "Interface_0_incorrectly_extends_interface_1_2430", "Interface '{0}' incorrectly extends interface '{1}'."),
        Enum_name_cannot_be_0: diag(2431, ts.DiagnosticCategory.Error, "Enum_name_cannot_be_0_2431", "Enum name cannot be '{0}'."),
        In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: diag(2432, ts.DiagnosticCategory.Error, "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."),
        A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: diag(2433, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", "A namespace declaration cannot be in a different file from a class or function with which it is merged."),
        A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: diag(2434, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", "A namespace declaration cannot be located prior to a class or function with which it is merged."),
        Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces: diag(2435, ts.DiagnosticCategory.Error, "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", "Ambient modules cannot be nested in other modules or namespaces."),
        Ambient_module_declaration_cannot_specify_relative_module_name: diag(2436, ts.DiagnosticCategory.Error, "Ambient_module_declaration_cannot_specify_relative_module_name_2436", "Ambient module declaration cannot specify relative module name."),
        Module_0_is_hidden_by_a_local_declaration_with_the_same_name: diag(2437, ts.DiagnosticCategory.Error, "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", "Module '{0}' is hidden by a local declaration with the same name."),
        Import_name_cannot_be_0: diag(2438, ts.DiagnosticCategory.Error, "Import_name_cannot_be_0_2438", "Import name cannot be '{0}'."),
        Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: diag(2439, ts.DiagnosticCategory.Error, "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", "Import or export declaration in an ambient module declaration cannot reference module through relative module name."),
        Import_declaration_conflicts_with_local_declaration_of_0: diag(2440, ts.DiagnosticCategory.Error, "Import_declaration_conflicts_with_local_declaration_of_0_2440", "Import declaration conflicts with local declaration of '{0}'."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: diag(2441, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."),
        Types_have_separate_declarations_of_a_private_property_0: diag(2442, ts.DiagnosticCategory.Error, "Types_have_separate_declarations_of_a_private_property_0_2442", "Types have separate declarations of a private property '{0}'."),
        Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: diag(2443, ts.DiagnosticCategory.Error, "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."),
        Property_0_is_protected_in_type_1_but_public_in_type_2: diag(2444, ts.DiagnosticCategory.Error, "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", "Property '{0}' is protected in type '{1}' but public in type '{2}'."),
        Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: diag(2445, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."),
        Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: diag(2446, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", "Property '{0}' is protected and only accessible through an instance of class '{1}'."),
        The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: diag(2447, ts.DiagnosticCategory.Error, "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."),
        Block_scoped_variable_0_used_before_its_declaration: diag(2448, ts.DiagnosticCategory.Error, "Block_scoped_variable_0_used_before_its_declaration_2448", "Block-scoped variable '{0}' used before its declaration."),
        Class_0_used_before_its_declaration: diag(2449, ts.DiagnosticCategory.Error, "Class_0_used_before_its_declaration_2449", "Class '{0}' used before its declaration."),
        Enum_0_used_before_its_declaration: diag(2450, ts.DiagnosticCategory.Error, "Enum_0_used_before_its_declaration_2450", "Enum '{0}' used before its declaration."),
        Cannot_redeclare_block_scoped_variable_0: diag(2451, ts.DiagnosticCategory.Error, "Cannot_redeclare_block_scoped_variable_0_2451", "Cannot redeclare block-scoped variable '{0}'."),
        An_enum_member_cannot_have_a_numeric_name: diag(2452, ts.DiagnosticCategory.Error, "An_enum_member_cannot_have_a_numeric_name_2452", "An enum member cannot have a numeric name."),
        The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: diag(2453, ts.DiagnosticCategory.Error, "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."),
        Variable_0_is_used_before_being_assigned: diag(2454, ts.DiagnosticCategory.Error, "Variable_0_is_used_before_being_assigned_2454", "Variable '{0}' is used before being assigned."),
        Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: diag(2455, ts.DiagnosticCategory.Error, "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'."),
        Type_alias_0_circularly_references_itself: diag(2456, ts.DiagnosticCategory.Error, "Type_alias_0_circularly_references_itself_2456", "Type alias '{0}' circularly references itself."),
        Type_alias_name_cannot_be_0: diag(2457, ts.DiagnosticCategory.Error, "Type_alias_name_cannot_be_0_2457", "Type alias name cannot be '{0}'."),
        An_AMD_module_cannot_have_multiple_name_assignments: diag(2458, ts.DiagnosticCategory.Error, "An_AMD_module_cannot_have_multiple_name_assignments_2458", "An AMD module cannot have multiple name assignments."),
        Type_0_has_no_property_1_and_no_string_index_signature: diag(2459, ts.DiagnosticCategory.Error, "Type_0_has_no_property_1_and_no_string_index_signature_2459", "Type '{0}' has no property '{1}' and no string index signature."),
        Type_0_has_no_property_1: diag(2460, ts.DiagnosticCategory.Error, "Type_0_has_no_property_1_2460", "Type '{0}' has no property '{1}'."),
        Type_0_is_not_an_array_type: diag(2461, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_2461", "Type '{0}' is not an array type."),
        A_rest_element_must_be_last_in_a_destructuring_pattern: diag(2462, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", "A rest element must be last in a destructuring pattern."),
        A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: diag(2463, ts.DiagnosticCategory.Error, "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", "A binding pattern parameter cannot be optional in an implementation signature."),
        A_computed_property_name_must_be_of_type_string_number_symbol_or_any: diag(2464, ts.DiagnosticCategory.Error, "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."),
        this_cannot_be_referenced_in_a_computed_property_name: diag(2465, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_computed_property_name_2465", "'this' cannot be referenced in a computed property name."),
        super_cannot_be_referenced_in_a_computed_property_name: diag(2466, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_a_computed_property_name_2466", "'super' cannot be referenced in a computed property name."),
        A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: diag(2467, ts.DiagnosticCategory.Error, "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", "A computed property name cannot reference a type parameter from its containing type."),
        Cannot_find_global_value_0: diag(2468, ts.DiagnosticCategory.Error, "Cannot_find_global_value_0_2468", "Cannot find global value '{0}'."),
        The_0_operator_cannot_be_applied_to_type_symbol: diag(2469, ts.DiagnosticCategory.Error, "The_0_operator_cannot_be_applied_to_type_symbol_2469", "The '{0}' operator cannot be applied to type 'symbol'."),
        Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: diag(2470, ts.DiagnosticCategory.Error, "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", "'Symbol' reference does not refer to the global Symbol constructor object."),
        A_computed_property_name_of_the_form_0_must_be_of_type_symbol: diag(2471, ts.DiagnosticCategory.Error, "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", "A computed property name of the form '{0}' must be of type 'symbol'."),
        Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: diag(2472, ts.DiagnosticCategory.Error, "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."),
        Enum_declarations_must_all_be_const_or_non_const: diag(2473, ts.DiagnosticCategory.Error, "Enum_declarations_must_all_be_const_or_non_const_2473", "Enum declarations must all be const or non-const."),
        In_const_enum_declarations_member_initializer_must_be_constant_expression: diag(2474, ts.DiagnosticCategory.Error, "In_const_enum_declarations_member_initializer_must_be_constant_expression_2474", "In 'const' enum declarations member initializer must be constant expression."),
        const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: diag(2475, ts.DiagnosticCategory.Error, "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment."),
        A_const_enum_member_can_only_be_accessed_using_a_string_literal: diag(2476, ts.DiagnosticCategory.Error, "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", "A const enum member can only be accessed using a string literal."),
        const_enum_member_initializer_was_evaluated_to_a_non_finite_value: diag(2477, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", "'const' enum member initializer was evaluated to a non-finite value."),
        const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: diag(2478, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", "'const' enum member initializer was evaluated to disallowed value 'NaN'."),
        Property_0_does_not_exist_on_const_enum_1: diag(2479, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_const_enum_1_2479", "Property '{0}' does not exist on 'const' enum '{1}'."),
        let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: diag(2480, ts.DiagnosticCategory.Error, "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", "'let' is not allowed to be used as a name in 'let' or 'const' declarations."),
        Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: diag(2481, ts.DiagnosticCategory.Error, "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."),
        The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: diag(2483, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", "The left-hand side of a 'for...of' statement cannot use a type annotation."),
        Export_declaration_conflicts_with_exported_declaration_of_0: diag(2484, ts.DiagnosticCategory.Error, "Export_declaration_conflicts_with_exported_declaration_of_0_2484", "Export declaration conflicts with exported declaration of '{0}'."),
        The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access: diag(2487, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", "The left-hand side of a 'for...of' statement must be a variable or a property access."),
        Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2488, ts.DiagnosticCategory.Error, "Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", "Type must have a '[Symbol.iterator]()' method that returns an iterator."),
        An_iterator_must_have_a_next_method: diag(2489, ts.DiagnosticCategory.Error, "An_iterator_must_have_a_next_method_2489", "An iterator must have a 'next()' method."),
        The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property: diag(2490, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property_2490", "The type returned by the 'next()' method of an iterator must have a 'value' property."),
        The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: diag(2491, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."),
        Cannot_redeclare_identifier_0_in_catch_clause: diag(2492, ts.DiagnosticCategory.Error, "Cannot_redeclare_identifier_0_in_catch_clause_2492", "Cannot redeclare identifier '{0}' in catch clause."),
        Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2: diag(2493, ts.DiagnosticCategory.Error, "Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2_2493", "Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'."),
        Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher: diag(2494, ts.DiagnosticCategory.Error, "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."),
        Type_0_is_not_an_array_type_or_a_string_type: diag(2495, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_2495", "Type '{0}' is not an array type or a string type."),
        The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression: diag(2496, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression."),
        Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct: diag(2497, ts.DiagnosticCategory.Error, "Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497", "Module '{0}' resolves to a non-module entity and cannot be imported using this construct."),
        Module_0_uses_export_and_cannot_be_used_with_export_Asterisk: diag(2498, ts.DiagnosticCategory.Error, "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", "Module '{0}' uses 'export =' and cannot be used with 'export *'."),
        An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2499, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", "An interface can only extend an identifier/qualified-name with optional type arguments."),
        A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2500, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", "A class can only implement an identifier/qualified-name with optional type arguments."),
        A_rest_element_cannot_contain_a_binding_pattern: diag(2501, ts.DiagnosticCategory.Error, "A_rest_element_cannot_contain_a_binding_pattern_2501", "A rest element cannot contain a binding pattern."),
        _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: diag(2502, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", "'{0}' is referenced directly or indirectly in its own type annotation."),
        Cannot_find_namespace_0: diag(2503, ts.DiagnosticCategory.Error, "Cannot_find_namespace_0_2503", "Cannot find namespace '{0}'."),
        Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator: diag(2504, ts.DiagnosticCategory.Error, "Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", "Type must have a '[Symbol.asyncIterator]()' method that returns an async iterator."),
        A_generator_cannot_have_a_void_type_annotation: diag(2505, ts.DiagnosticCategory.Error, "A_generator_cannot_have_a_void_type_annotation_2505", "A generator cannot have a 'void' type annotation."),
        _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: diag(2506, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", "'{0}' is referenced directly or indirectly in its own base expression."),
        Type_0_is_not_a_constructor_function_type: diag(2507, ts.DiagnosticCategory.Error, "Type_0_is_not_a_constructor_function_type_2507", "Type '{0}' is not a constructor function type."),
        No_base_constructor_has_the_specified_number_of_type_arguments: diag(2508, ts.DiagnosticCategory.Error, "No_base_constructor_has_the_specified_number_of_type_arguments_2508", "No base constructor has the specified number of type arguments."),
        Base_constructor_return_type_0_is_not_a_class_or_interface_type: diag(2509, ts.DiagnosticCategory.Error, "Base_constructor_return_type_0_is_not_a_class_or_interface_type_2509", "Base constructor return type '{0}' is not a class or interface type."),
        Base_constructors_must_all_have_the_same_return_type: diag(2510, ts.DiagnosticCategory.Error, "Base_constructors_must_all_have_the_same_return_type_2510", "Base constructors must all have the same return type."),
        Cannot_create_an_instance_of_the_abstract_class_0: diag(2511, ts.DiagnosticCategory.Error, "Cannot_create_an_instance_of_the_abstract_class_0_2511", "Cannot create an instance of the abstract class '{0}'."),
        Overload_signatures_must_all_be_abstract_or_non_abstract: diag(2512, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", "Overload signatures must all be abstract or non-abstract."),
        Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: diag(2513, ts.DiagnosticCategory.Error, "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."),
        Classes_containing_abstract_methods_must_be_marked_abstract: diag(2514, ts.DiagnosticCategory.Error, "Classes_containing_abstract_methods_must_be_marked_abstract_2514", "Classes containing abstract methods must be marked abstract."),
        Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: diag(2515, ts.DiagnosticCategory.Error, "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'."),
        All_declarations_of_an_abstract_method_must_be_consecutive: diag(2516, ts.DiagnosticCategory.Error, "All_declarations_of_an_abstract_method_must_be_consecutive_2516", "All declarations of an abstract method must be consecutive."),
        Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: diag(2517, ts.DiagnosticCategory.Error, "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", "Cannot assign an abstract constructor type to a non-abstract constructor type."),
        A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard: diag(2518, ts.DiagnosticCategory.Error, "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", "A 'this'-based type guard is not compatible with a parameter-based type guard."),
        An_async_iterator_must_have_a_next_method: diag(2519, ts.DiagnosticCategory.Error, "An_async_iterator_must_have_a_next_method_2519", "An async iterator must have a 'next()' method."),
        Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: diag(2520, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."),
        Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: diag(2521, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", "Expression resolves to variable declaration '{0}' that compiler uses to support async functions."),
        The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method: diag(2522, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522", "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method."),
        yield_expressions_cannot_be_used_in_a_parameter_initializer: diag(2523, ts.DiagnosticCategory.Error, "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", "'yield' expressions cannot be used in a parameter initializer."),
        await_expressions_cannot_be_used_in_a_parameter_initializer: diag(2524, ts.DiagnosticCategory.Error, "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", "'await' expressions cannot be used in a parameter initializer."),
        Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: diag(2525, ts.DiagnosticCategory.Error, "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", "Initializer provides no value for this binding element and the binding element has no default value."),
        A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface: diag(2526, ts.DiagnosticCategory.Error, "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", "A 'this' type is available only in a non-static member of a class or interface."),
        The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary: diag(2527, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary_2527", "The inferred type of '{0}' references an inaccessible 'this' type. A type annotation is necessary."),
        A_module_cannot_have_multiple_default_exports: diag(2528, ts.DiagnosticCategory.Error, "A_module_cannot_have_multiple_default_exports_2528", "A module cannot have multiple default exports."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: diag(2529, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."),
        Property_0_is_incompatible_with_index_signature: diag(2530, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_index_signature_2530", "Property '{0}' is incompatible with index signature."),
        Object_is_possibly_null: diag(2531, ts.DiagnosticCategory.Error, "Object_is_possibly_null_2531", "Object is possibly 'null'."),
        Object_is_possibly_undefined: diag(2532, ts.DiagnosticCategory.Error, "Object_is_possibly_undefined_2532", "Object is possibly 'undefined'."),
        Object_is_possibly_null_or_undefined: diag(2533, ts.DiagnosticCategory.Error, "Object_is_possibly_null_or_undefined_2533", "Object is possibly 'null' or 'undefined'."),
        A_function_returning_never_cannot_have_a_reachable_end_point: diag(2534, ts.DiagnosticCategory.Error, "A_function_returning_never_cannot_have_a_reachable_end_point_2534", "A function returning 'never' cannot have a reachable end point."),
        Enum_type_0_has_members_with_initializers_that_are_not_literals: diag(2535, ts.DiagnosticCategory.Error, "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535", "Enum type '{0}' has members with initializers that are not literals."),
        Type_0_cannot_be_used_to_index_type_1: diag(2536, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_to_index_type_1_2536", "Type '{0}' cannot be used to index type '{1}'."),
        Type_0_has_no_matching_index_signature_for_type_1: diag(2537, ts.DiagnosticCategory.Error, "Type_0_has_no_matching_index_signature_for_type_1_2537", "Type '{0}' has no matching index signature for type '{1}'."),
        Type_0_cannot_be_used_as_an_index_type: diag(2538, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_as_an_index_type_2538", "Type '{0}' cannot be used as an index type."),
        Cannot_assign_to_0_because_it_is_not_a_variable: diag(2539, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_not_a_variable_2539", "Cannot assign to '{0}' because it is not a variable."),
        Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property: diag(2540, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property_2540", "Cannot assign to '{0}' because it is a constant or a read-only property."),
        The_target_of_an_assignment_must_be_a_variable_or_a_property_access: diag(2541, ts.DiagnosticCategory.Error, "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541", "The target of an assignment must be a variable or a property access."),
        Index_signature_in_type_0_only_permits_reading: diag(2542, ts.DiagnosticCategory.Error, "Index_signature_in_type_0_only_permits_reading_2542", "Index signature in type '{0}' only permits reading."),
        Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference: diag(2543, ts.DiagnosticCategory.Error, "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."),
        Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference: diag(2544, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."),
        A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any: diag(2545, ts.DiagnosticCategory.Error, "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", "A mixin class must have a constructor with a single rest parameter of type 'any[]'."),
        Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1: diag(2546, ts.DiagnosticCategory.Error, "Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1_2546", "Property '{0}' has conflicting declarations and is inaccessible in type '{1}'."),
        The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property: diag(2547, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value__2547", "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property."),
        Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2548, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2549, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Generic_type_instantiation_is_excessively_deep_and_possibly_infinite: diag(2550, ts.DiagnosticCategory.Error, "Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550", "Generic type instantiation is excessively deep and possibly infinite."),
        Property_0_does_not_exist_on_type_1_Did_you_mean_2: diag(2551, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"),
        Cannot_find_name_0_Did_you_mean_1: diag(2552, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_1_2552", "Cannot find name '{0}'. Did you mean '{1}'?"),
        Computed_values_are_not_permitted_in_an_enum_with_string_valued_members: diag(2553, ts.DiagnosticCategory.Error, "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", "Computed values are not permitted in an enum with string valued members."),
        Expected_0_arguments_but_got_1: diag(2554, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_2554", "Expected {0} arguments, but got {1}."),
        Expected_at_least_0_arguments_but_got_1: diag(2555, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_2555", "Expected at least {0} arguments, but got {1}."),
        Expected_0_arguments_but_got_a_minimum_of_1: diag(2556, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_a_minimum_of_1_2556", "Expected {0} arguments, but got a minimum of {1}."),
        Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."),
        Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."),
        Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."),
        Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"),
        Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2: diag(2561, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"),
        Base_class_expressions_cannot_reference_class_type_parameters: diag(2562, ts.DiagnosticCategory.Error, "Base_class_expressions_cannot_reference_class_type_parameters_2562", "Base class expressions cannot reference class type parameters."),
        The_containing_function_or_module_body_is_too_large_for_control_flow_analysis: diag(2563, ts.DiagnosticCategory.Error, "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", "The containing function or module body is too large for control flow analysis."),
        JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."),
        The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."),
        JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."),
        Property_0_in_type_1_is_not_assignable_to_type_2: diag(2603, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_type_2_2603", "Property '{0}' in type '{1}' is not assignable to type '{2}'."),
        JSX_element_type_0_does_not_have_any_construct_or_call_signatures: diag(2604, ts.DiagnosticCategory.Error, "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", "JSX element type '{0}' does not have any construct or call signatures."),
        JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: diag(2605, ts.DiagnosticCategory.Error, "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", "JSX element type '{0}' is not a constructor function for JSX elements."),
        Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: diag(2606, ts.DiagnosticCategory.Error, "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", "Property '{0}' of JSX spread attribute is not assignable to target property."),
        JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: diag(2607, ts.DiagnosticCategory.Error, "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", "JSX element class does not support attributes because it does not have a '{0}' property."),
        The_global_type_JSX_0_may_not_have_more_than_one_property: diag(2608, ts.DiagnosticCategory.Error, "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", "The global type 'JSX.{0}' may not have more than one property."),
        JSX_spread_child_must_be_an_array_type: diag(2609, ts.DiagnosticCategory.Error, "JSX_spread_child_must_be_an_array_type_2609", "JSX spread child must be an array type."),
        Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity: diag(2649, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."),
        A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: diag(2651, ts.DiagnosticCategory.Error, "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."),
        Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: diag(2652, ts.DiagnosticCategory.Error, "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."),
        Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1: diag(2653, ts.DiagnosticCategory.Error, "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."),
        Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: diag(2654, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition."),
        Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition: diag(2656, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition."),
        JSX_expressions_must_have_one_parent_element: diag(2657, ts.DiagnosticCategory.Error, "JSX_expressions_must_have_one_parent_element_2657", "JSX expressions must have one parent element."),
        Type_0_provides_no_match_for_the_signature_1: diag(2658, ts.DiagnosticCategory.Error, "Type_0_provides_no_match_for_the_signature_1_2658", "Type '{0}' provides no match for the signature '{1}'."),
        super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher: diag(2659, ts.DiagnosticCategory.Error, "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."),
        super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions: diag(2660, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", "'super' can only be referenced in members of derived classes or object literal expressions."),
        Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module: diag(2661, ts.DiagnosticCategory.Error, "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", "Cannot export '{0}'. Only local declarations can be exported from a module."),
        Cannot_find_name_0_Did_you_mean_the_static_member_1_0: diag(2662, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"),
        Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: diag(2663, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"),
        Invalid_module_name_in_augmentation_module_0_cannot_be_found: diag(2664, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", "Invalid module name in augmentation, module '{0}' cannot be found."),
        Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented: diag(2665, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."),
        Exports_and_export_assignments_are_not_permitted_in_module_augmentations: diag(2666, ts.DiagnosticCategory.Error, "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", "Exports and export assignments are not permitted in module augmentations."),
        Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module: diag(2667, ts.DiagnosticCategory.Error, "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."),
        export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible: diag(2668, ts.DiagnosticCategory.Error, "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."),
        Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations: diag(2669, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."),
        Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context: diag(2670, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."),
        Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity: diag(2671, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", "Cannot augment module '{0}' because it resolves to a non-module entity."),
        Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: diag(2672, ts.DiagnosticCategory.Error, "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", "Cannot assign a '{0}' constructor type to a '{1}' constructor type."),
        Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: diag(2673, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", "Constructor of class '{0}' is private and only accessible within the class declaration."),
        Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration: diag(2674, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", "Constructor of class '{0}' is protected and only accessible within the class declaration."),
        Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: diag(2675, ts.DiagnosticCategory.Error, "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", "Cannot extend a class '{0}'. Class constructor is marked as private."),
        Accessors_must_both_be_abstract_or_non_abstract: diag(2676, ts.DiagnosticCategory.Error, "Accessors_must_both_be_abstract_or_non_abstract_2676", "Accessors must both be abstract or non-abstract."),
        A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: diag(2677, ts.DiagnosticCategory.Error, "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", "A type predicate's type must be assignable to its parameter's type."),
        Type_0_is_not_comparable_to_type_1: diag(2678, ts.DiagnosticCategory.Error, "Type_0_is_not_comparable_to_type_1_2678", "Type '{0}' is not comparable to type '{1}'."),
        A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void: diag(2679, ts.DiagnosticCategory.Error, "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."),
        A_0_parameter_must_be_the_first_parameter: diag(2680, ts.DiagnosticCategory.Error, "A_0_parameter_must_be_the_first_parameter_2680", "A '{0}' parameter must be the first parameter."),
        A_constructor_cannot_have_a_this_parameter: diag(2681, ts.DiagnosticCategory.Error, "A_constructor_cannot_have_a_this_parameter_2681", "A constructor cannot have a 'this' parameter."),
        get_and_set_accessor_must_have_the_same_this_type: diag(2682, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_this_type_2682", "'get' and 'set' accessor must have the same 'this' type."),
        this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: diag(2683, ts.DiagnosticCategory.Error, "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", "'this' implicitly has type 'any' because it does not have a type annotation."),
        The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: diag(2684, ts.DiagnosticCategory.Error, "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."),
        The_this_types_of_each_signature_are_incompatible: diag(2685, ts.DiagnosticCategory.Error, "The_this_types_of_each_signature_are_incompatible_2685", "The 'this' types of each signature are incompatible."),
        _0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead: diag(2686, ts.DiagnosticCategory.Error, "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."),
        All_declarations_of_0_must_have_identical_modifiers: diag(2687, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_modifiers_2687", "All declarations of '{0}' must have identical modifiers."),
        Cannot_find_type_definition_file_for_0: diag(2688, ts.DiagnosticCategory.Error, "Cannot_find_type_definition_file_for_0_2688", "Cannot find type definition file for '{0}'."),
        Cannot_extend_an_interface_0_Did_you_mean_implements: diag(2689, ts.DiagnosticCategory.Error, "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", "Cannot extend an interface '{0}'. Did you mean 'implements'?"),
        An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: diag(2691, ts.DiagnosticCategory.Error, "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead."),
        _0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible: diag(2692, ts.DiagnosticCategory.Error, "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here: diag(2693, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", "'{0}' only refers to a type, but is being used as a value here."),
        Namespace_0_has_no_exported_member_1: diag(2694, ts.DiagnosticCategory.Error, "Namespace_0_has_no_exported_member_1_2694", "Namespace '{0}' has no exported member '{1}'."),
        Left_side_of_comma_operator_is_unused_and_has_no_side_effects: diag(2695, ts.DiagnosticCategory.Error, "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", "Left side of comma operator is unused and has no side effects."),
        The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead: diag(2696, ts.DiagnosticCategory.Error, "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"),
        An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2697, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        Spread_types_may_only_be_created_from_object_types: diag(2698, ts.DiagnosticCategory.Error, "Spread_types_may_only_be_created_from_object_types_2698", "Spread types may only be created from object types."),
        Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1: diag(2699, ts.DiagnosticCategory.Error, "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."),
        Rest_types_may_only_be_created_from_object_types: diag(2700, ts.DiagnosticCategory.Error, "Rest_types_may_only_be_created_from_object_types_2700", "Rest types may only be created from object types."),
        The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access: diag(2701, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", "The target of an object rest assignment must be a variable or a property access."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here: diag(2702, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", "'{0}' only refers to a type, but is being used as a namespace here."),
        The_operand_of_a_delete_operator_must_be_a_property_reference: diag(2703, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", "The operand of a delete operator must be a property reference."),
        The_operand_of_a_delete_operator_cannot_be_a_read_only_property: diag(2704, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", "The operand of a delete operator cannot be a read-only property."),
        An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2705, ts.DiagnosticCategory.Error, "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705", "An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Required_type_parameters_may_not_follow_optional_type_parameters: diag(2706, ts.DiagnosticCategory.Error, "Required_type_parameters_may_not_follow_optional_type_parameters_2706", "Required type parameters may not follow optional type parameters."),
        Generic_type_0_requires_between_1_and_2_type_arguments: diag(2707, ts.DiagnosticCategory.Error, "Generic_type_0_requires_between_1_and_2_type_arguments_2707", "Generic type '{0}' requires between {1} and {2} type arguments."),
        Cannot_use_namespace_0_as_a_value: diag(2708, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_value_2708", "Cannot use namespace '{0}' as a value."),
        Cannot_use_namespace_0_as_a_type: diag(2709, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_type_2709", "Cannot use namespace '{0}' as a type."),
        _0_are_specified_twice_The_attribute_named_0_will_be_overwritten: diag(2710, ts.DiagnosticCategory.Error, "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", "'{0}' are specified twice. The attribute named '{0}' will be overwritten."),
        A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2711, ts.DiagnosticCategory.Error, "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2712, ts.DiagnosticCategory.Error, "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712", "A dynamic import call in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1: diag(2713, ts.DiagnosticCategory.Error, "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"),
        The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context: diag(2714, ts.DiagnosticCategory.Error, "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", "The expression of an export assignment must be an identifier or qualified name in an ambient context."),
        Type_parameter_0_has_a_circular_default: diag(2716, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_default_2716", "Type parameter '{0}' has a circular default."),
        Import_declaration_0_is_using_private_name_1: diag(4000, ts.DiagnosticCategory.Error, "Import_declaration_0_is_using_private_name_1_4000", "Import declaration '{0}' is using private name '{1}'."),
        Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: diag(4002, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", "Type parameter '{0}' of exported class has or is using private name '{1}'."),
        Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: diag(4004, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", "Type parameter '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4006, ts.DiagnosticCategory.Error, "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4008, ts.DiagnosticCategory.Error, "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4010, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4012, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4014, ts.DiagnosticCategory.Error, "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4016, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", "Type parameter '{0}' of exported function has or is using private name '{1}'."),
        Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4019, ts.DiagnosticCategory.Error, "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", "Implements clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4020, ts.DiagnosticCategory.Error, "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", "'extends' clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: diag(4022, ts.DiagnosticCategory.Error, "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", "'extends' clause of exported interface '{0}' has or is using private name '{1}'."),
        Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4023, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."),
        Exported_variable_0_has_or_is_using_name_1_from_private_module_2: diag(4024, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."),
        Exported_variable_0_has_or_is_using_private_name_1: diag(4025, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_private_name_1_4025", "Exported variable '{0}' has or is using private name '{1}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4026, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4027, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4028, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", "Public static property '{0}' of exported class has or is using private name '{1}'."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4029, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4030, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4031, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", "Public property '{0}' of exported class has or is using private name '{1}'."),
        Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4032, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Property_0_of_exported_interface_has_or_is_using_private_name_1: diag(4033, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", "Property '{0}' of exported interface has or is using private name '{1}'."),
        Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4034, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_4034", "Parameter '{0}' of public static property setter from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1: diag(4035, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1_4035", "Parameter '{0}' of public static property setter from exported class has or is using private name '{1}'."),
        Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4036, ts.DiagnosticCategory.Error, "Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_4036", "Parameter '{0}' of public property setter from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1: diag(4037, ts.DiagnosticCategory.Error, "Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1_4037", "Parameter '{0}' of public property setter from exported class has or is using private name '{1}'."),
        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4038, ts.DiagnosticCategory.Error, "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_externa_4038", "Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4039, ts.DiagnosticCategory.Error, "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_4039", "Return type of public static property getter from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0: diag(4040, ts.DiagnosticCategory.Error, "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0_4040", "Return type of public static property getter from exported class has or is using private name '{0}'."),
        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4041, ts.DiagnosticCategory.Error, "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_modul_4041", "Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4042, ts.DiagnosticCategory.Error, "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_4042", "Return type of public property getter from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0: diag(4043, ts.DiagnosticCategory.Error, "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0_4043", "Return type of public property getter from exported class has or is using private name '{0}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4044, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4045, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", "Return type of constructor signature from exported interface has or is using private name '{0}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4046, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4047, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", "Return type of call signature from exported interface has or is using private name '{0}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4048, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4049, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", "Return type of index signature from exported interface has or is using private name '{0}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4050, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4051, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: diag(4052, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", "Return type of public static method from exported class has or is using private name '{0}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4053, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4054, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: diag(4055, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", "Return type of public method from exported class has or is using private name '{0}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4056, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: diag(4057, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", "Return type of method from exported interface has or is using private name '{0}'."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4058, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: diag(4059, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", "Return type of exported function has or is using name '{0}' from private module '{1}'."),
        Return_type_of_exported_function_has_or_is_using_private_name_0: diag(4060, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", "Return type of exported function has or is using private name '{0}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4061, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4062, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: diag(4063, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4064, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4065, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4066, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4067, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4068, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4069, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4070, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4071, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4072, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4073, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", "Parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4074, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4075, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", "Parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4076, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: diag(4077, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4078, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", "Parameter '{0}' of exported function has or is using private name '{1}'."),
        Exported_type_alias_0_has_or_is_using_private_name_1: diag(4081, ts.DiagnosticCategory.Error, "Exported_type_alias_0_has_or_is_using_private_name_1_4081", "Exported type alias '{0}' has or is using private name '{1}'."),
        Default_export_of_the_module_has_or_is_using_private_name_0: diag(4082, ts.DiagnosticCategory.Error, "Default_export_of_the_module_has_or_is_using_private_name_0_4082", "Default export of the module has or is using private name '{0}'."),
        Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1: diag(4083, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", "Type parameter '{0}' of exported type alias has or is using private name '{1}'."),
        Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict: diag(4090, ts.DiagnosticCategory.Message, "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090", "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4091, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4092, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."),
        Property_0_of_exported_class_expression_may_not_be_private_or_protected: diag(4094, ts.DiagnosticCategory.Error, "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094", "Property '{0}' of exported class expression may not be private or protected."),
        The_current_host_does_not_support_the_0_option: diag(5001, ts.DiagnosticCategory.Error, "The_current_host_does_not_support_the_0_option_5001", "The current host does not support the '{0}' option."),
        Cannot_find_the_common_subdirectory_path_for_the_input_files: diag(5009, ts.DiagnosticCategory.Error, "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", "Cannot find the common subdirectory path for the input files."),
        File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5010, ts.DiagnosticCategory.Error, "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."),
        File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0: diag(5011, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0_5011", "File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'."),
        Cannot_read_file_0_Colon_1: diag(5012, ts.DiagnosticCategory.Error, "Cannot_read_file_0_Colon_1_5012", "Cannot read file '{0}': {1}."),
        Failed_to_parse_file_0_Colon_1: diag(5014, ts.DiagnosticCategory.Error, "Failed_to_parse_file_0_Colon_1_5014", "Failed to parse file '{0}': {1}."),
        Unknown_compiler_option_0: diag(5023, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_5023", "Unknown compiler option '{0}'."),
        Compiler_option_0_requires_a_value_of_type_1: diag(5024, ts.DiagnosticCategory.Error, "Compiler_option_0_requires_a_value_of_type_1_5024", "Compiler option '{0}' requires a value of type {1}."),
        Could_not_write_file_0_Colon_1: diag(5033, ts.DiagnosticCategory.Error, "Could_not_write_file_0_Colon_1_5033", "Could not write file '{0}': {1}."),
        Option_project_cannot_be_mixed_with_source_files_on_a_command_line: diag(5042, ts.DiagnosticCategory.Error, "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", "Option 'project' cannot be mixed with source files on a command line."),
        Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher: diag(5047, ts.DiagnosticCategory.Error, "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."),
        Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: diag(5051, ts.DiagnosticCategory.Error, "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."),
        Option_0_cannot_be_specified_without_specifying_option_1: diag(5052, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_5052", "Option '{0}' cannot be specified without specifying option '{1}'."),
        Option_0_cannot_be_specified_with_option_1: diag(5053, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_with_option_1_5053", "Option '{0}' cannot be specified with option '{1}'."),
        A_tsconfig_json_file_is_already_defined_at_Colon_0: diag(5054, ts.DiagnosticCategory.Error, "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", "A 'tsconfig.json' file is already defined at: '{0}'."),
        Cannot_write_file_0_because_it_would_overwrite_input_file: diag(5055, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", "Cannot write file '{0}' because it would overwrite input file."),
        Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: diag(5056, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", "Cannot write file '{0}' because it would be overwritten by multiple input files."),
        Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0: diag(5057, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", "Cannot find a tsconfig.json file at the specified directory: '{0}'."),
        The_specified_path_does_not_exist_Colon_0: diag(5058, ts.DiagnosticCategory.Error, "The_specified_path_does_not_exist_Colon_0_5058", "The specified path does not exist: '{0}'."),
        Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: diag(5059, ts.DiagnosticCategory.Error, "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."),
        Option_paths_cannot_be_used_without_specifying_baseUrl_option: diag(5060, ts.DiagnosticCategory.Error, "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", "Option 'paths' cannot be used without specifying '--baseUrl' option."),
        Pattern_0_can_have_at_most_one_Asterisk_character: diag(5061, ts.DiagnosticCategory.Error, "Pattern_0_can_have_at_most_one_Asterisk_character_5061", "Pattern '{0}' can have at most one '*' character."),
        Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: diag(5062, ts.DiagnosticCategory.Error, "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", "Substitution '{0}' in pattern '{1}' in can have at most one '*' character."),
        Substitutions_for_pattern_0_should_be_an_array: diag(5063, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_should_be_an_array_5063", "Substitutions for pattern '{0}' should be an array."),
        Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: diag(5064, ts.DiagnosticCategory.Error, "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."),
        File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5065, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."),
        Substitutions_for_pattern_0_shouldn_t_be_an_empty_array: diag(5066, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", "Substitutions for pattern '{0}' shouldn't be an empty array."),
        Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name: diag(5067, ts.DiagnosticCategory.Error, "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."),
        Concatenate_and_emit_output_to_single_file: diag(6001, ts.DiagnosticCategory.Message, "Concatenate_and_emit_output_to_single_file_6001", "Concatenate and emit output to single file."),
        Generates_corresponding_d_ts_file: diag(6002, ts.DiagnosticCategory.Message, "Generates_corresponding_d_ts_file_6002", "Generates corresponding '.d.ts' file."),
        Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: diag(6003, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", "Specify the location where debugger should locate map files instead of generated locations."),
        Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: diag(6004, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", "Specify the location where debugger should locate TypeScript files instead of source locations."),
        Watch_input_files: diag(6005, ts.DiagnosticCategory.Message, "Watch_input_files_6005", "Watch input files."),
        Redirect_output_structure_to_the_directory: diag(6006, ts.DiagnosticCategory.Message, "Redirect_output_structure_to_the_directory_6006", "Redirect output structure to the directory."),
        Do_not_erase_const_enum_declarations_in_generated_code: diag(6007, ts.DiagnosticCategory.Message, "Do_not_erase_const_enum_declarations_in_generated_code_6007", "Do not erase const enum declarations in generated code."),
        Do_not_emit_outputs_if_any_errors_were_reported: diag(6008, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_if_any_errors_were_reported_6008", "Do not emit outputs if any errors were reported."),
        Do_not_emit_comments_to_output: diag(6009, ts.DiagnosticCategory.Message, "Do_not_emit_comments_to_output_6009", "Do not emit comments to output."),
        Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."),
        Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."),
        Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."),
        Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."),
        Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."),
        Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."),
        Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."),
        Print_the_compiler_s_version: diag(6019, ts.DiagnosticCategory.Message, "Print_the_compiler_s_version_6019", "Print the compiler's version."),
        Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json: diag(6020, ts.DiagnosticCategory.Message, "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."),
        Syntax_Colon_0: diag(6023, ts.DiagnosticCategory.Message, "Syntax_Colon_0_6023", "Syntax: {0}"),
        options: diag(6024, ts.DiagnosticCategory.Message, "options_6024", "options"),
        file: diag(6025, ts.DiagnosticCategory.Message, "file_6025", "file"),
        Examples_Colon_0: diag(6026, ts.DiagnosticCategory.Message, "Examples_Colon_0_6026", "Examples: {0}"),
        Options_Colon: diag(6027, ts.DiagnosticCategory.Message, "Options_Colon_6027", "Options:"),
        Version_0: diag(6029, ts.DiagnosticCategory.Message, "Version_0_6029", "Version {0}"),
        Insert_command_line_options_and_files_from_a_file: diag(6030, ts.DiagnosticCategory.Message, "Insert_command_line_options_and_files_from_a_file_6030", "Insert command line options and files from a file."),
        File_change_detected_Starting_incremental_compilation: diag(6032, ts.DiagnosticCategory.Message, "File_change_detected_Starting_incremental_compilation_6032", "File change detected. Starting incremental compilation..."),
        KIND: diag(6034, ts.DiagnosticCategory.Message, "KIND_6034", "KIND"),
        FILE: diag(6035, ts.DiagnosticCategory.Message, "FILE_6035", "FILE"),
        VERSION: diag(6036, ts.DiagnosticCategory.Message, "VERSION_6036", "VERSION"),
        LOCATION: diag(6037, ts.DiagnosticCategory.Message, "LOCATION_6037", "LOCATION"),
        DIRECTORY: diag(6038, ts.DiagnosticCategory.Message, "DIRECTORY_6038", "DIRECTORY"),
        STRATEGY: diag(6039, ts.DiagnosticCategory.Message, "STRATEGY_6039", "STRATEGY"),
        FILE_OR_DIRECTORY: diag(6040, ts.DiagnosticCategory.Message, "FILE_OR_DIRECTORY_6040", "FILE OR DIRECTORY"),
        Compilation_complete_Watching_for_file_changes: diag(6042, ts.DiagnosticCategory.Message, "Compilation_complete_Watching_for_file_changes_6042", "Compilation complete. Watching for file changes."),
        Generates_corresponding_map_file: diag(6043, ts.DiagnosticCategory.Message, "Generates_corresponding_map_file_6043", "Generates corresponding '.map' file."),
        Compiler_option_0_expects_an_argument: diag(6044, ts.DiagnosticCategory.Error, "Compiler_option_0_expects_an_argument_6044", "Compiler option '{0}' expects an argument."),
        Unterminated_quoted_string_in_response_file_0: diag(6045, ts.DiagnosticCategory.Error, "Unterminated_quoted_string_in_response_file_0_6045", "Unterminated quoted string in response file '{0}'."),
        Argument_for_0_option_must_be_Colon_1: diag(6046, ts.DiagnosticCategory.Error, "Argument_for_0_option_must_be_Colon_1_6046", "Argument for '{0}' option must be: {1}."),
        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: diag(6048, ts.DiagnosticCategory.Error, "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'."),
        Unsupported_locale_0: diag(6049, ts.DiagnosticCategory.Error, "Unsupported_locale_0_6049", "Unsupported locale '{0}'."),
        Unable_to_open_file_0: diag(6050, ts.DiagnosticCategory.Error, "Unable_to_open_file_0_6050", "Unable to open file '{0}'."),
        Corrupted_locale_file_0: diag(6051, ts.DiagnosticCategory.Error, "Corrupted_locale_file_0_6051", "Corrupted locale file {0}."),
        Raise_error_on_expressions_and_declarations_with_an_implied_any_type: diag(6052, ts.DiagnosticCategory.Message, "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", "Raise error on expressions and declarations with an implied 'any' type."),
        File_0_not_found: diag(6053, ts.DiagnosticCategory.Error, "File_0_not_found_6053", "File '{0}' not found."),
        File_0_has_unsupported_extension_The_only_supported_extensions_are_1: diag(6054, ts.DiagnosticCategory.Error, "File_0_has_unsupported_extension_The_only_supported_extensions_are_1_6054", "File '{0}' has unsupported extension. The only supported extensions are {1}."),
        Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: diag(6055, ts.DiagnosticCategory.Message, "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", "Suppress noImplicitAny errors for indexing objects lacking index signatures."),
        Do_not_emit_declarations_for_code_that_has_an_internal_annotation: diag(6056, ts.DiagnosticCategory.Message, "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", "Do not emit declarations for code that has an '@internal' annotation."),
        Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: diag(6058, ts.DiagnosticCategory.Message, "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", "Specify the root directory of input files. Use to control the output directory structure with --outDir."),
        File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: diag(6059, ts.DiagnosticCategory.Error, "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."),
        Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: diag(6060, ts.DiagnosticCategory.Message, "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."),
        NEWLINE: diag(6061, ts.DiagnosticCategory.Message, "NEWLINE_6061", "NEWLINE"),
        Option_0_can_only_be_specified_in_tsconfig_json_file: diag(6064, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_6064", "Option '{0}' can only be specified in 'tsconfig.json' file."),
        Enables_experimental_support_for_ES7_decorators: diag(6065, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_decorators_6065", "Enables experimental support for ES7 decorators."),
        Enables_experimental_support_for_emitting_type_metadata_for_decorators: diag(6066, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", "Enables experimental support for emitting type metadata for decorators."),
        Enables_experimental_support_for_ES7_async_functions: diag(6068, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_async_functions_6068", "Enables experimental support for ES7 async functions."),
        Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: diag(6069, ts.DiagnosticCategory.Message, "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)."),
        Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: diag(6070, ts.DiagnosticCategory.Message, "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", "Initializes a TypeScript project and creates a tsconfig.json file."),
        Successfully_created_a_tsconfig_json_file: diag(6071, ts.DiagnosticCategory.Message, "Successfully_created_a_tsconfig_json_file_6071", "Successfully created a tsconfig.json file."),
        Suppress_excess_property_checks_for_object_literals: diag(6072, ts.DiagnosticCategory.Message, "Suppress_excess_property_checks_for_object_literals_6072", "Suppress excess property checks for object literals."),
        Stylize_errors_and_messages_using_color_and_context_experimental: diag(6073, ts.DiagnosticCategory.Message, "Stylize_errors_and_messages_using_color_and_context_experimental_6073", "Stylize errors and messages using color and context (experimental)."),
        Do_not_report_errors_on_unused_labels: diag(6074, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unused_labels_6074", "Do not report errors on unused labels."),
        Report_error_when_not_all_code_paths_in_function_return_a_value: diag(6075, ts.DiagnosticCategory.Message, "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", "Report error when not all code paths in function return a value."),
        Report_errors_for_fallthrough_cases_in_switch_statement: diag(6076, ts.DiagnosticCategory.Message, "Report_errors_for_fallthrough_cases_in_switch_statement_6076", "Report errors for fallthrough cases in switch statement."),
        Do_not_report_errors_on_unreachable_code: diag(6077, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unreachable_code_6077", "Do not report errors on unreachable code."),
        Disallow_inconsistently_cased_references_to_the_same_file: diag(6078, ts.DiagnosticCategory.Message, "Disallow_inconsistently_cased_references_to_the_same_file_6078", "Disallow inconsistently-cased references to the same file."),
        Specify_library_files_to_be_included_in_the_compilation_Colon: diag(6079, ts.DiagnosticCategory.Message, "Specify_library_files_to_be_included_in_the_compilation_Colon_6079", "Specify library files to be included in the compilation: "),
        Specify_JSX_code_generation_Colon_preserve_react_native_or_react: diag(6080, ts.DiagnosticCategory.Message, "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080", "Specify JSX code generation: 'preserve', 'react-native', or 'react'."),
        File_0_has_an_unsupported_extension_so_skipping_it: diag(6081, ts.DiagnosticCategory.Message, "File_0_has_an_unsupported_extension_so_skipping_it_6081", "File '{0}' has an unsupported extension, so skipping it."),
        Only_amd_and_system_modules_are_supported_alongside_0: diag(6082, ts.DiagnosticCategory.Error, "Only_amd_and_system_modules_are_supported_alongside_0_6082", "Only 'amd' and 'system' modules are supported alongside --{0}."),
        Base_directory_to_resolve_non_absolute_module_names: diag(6083, ts.DiagnosticCategory.Message, "Base_directory_to_resolve_non_absolute_module_names_6083", "Base directory to resolve non-absolute module names."),
        Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit: diag(6084, ts.DiagnosticCategory.Message, "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"),
        Enable_tracing_of_the_name_resolution_process: diag(6085, ts.DiagnosticCategory.Message, "Enable_tracing_of_the_name_resolution_process_6085", "Enable tracing of the name resolution process."),
        Resolving_module_0_from_1: diag(6086, ts.DiagnosticCategory.Message, "Resolving_module_0_from_1_6086", "======== Resolving module '{0}' from '{1}'. ========"),
        Explicitly_specified_module_resolution_kind_Colon_0: diag(6087, ts.DiagnosticCategory.Message, "Explicitly_specified_module_resolution_kind_Colon_0_6087", "Explicitly specified module resolution kind: '{0}'."),
        Module_resolution_kind_is_not_specified_using_0: diag(6088, ts.DiagnosticCategory.Message, "Module_resolution_kind_is_not_specified_using_0_6088", "Module resolution kind is not specified, using '{0}'."),
        Module_name_0_was_successfully_resolved_to_1: diag(6089, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_6089", "======== Module name '{0}' was successfully resolved to '{1}'. ========"),
        Module_name_0_was_not_resolved: diag(6090, ts.DiagnosticCategory.Message, "Module_name_0_was_not_resolved_6090", "======== Module name '{0}' was not resolved. ========"),
        paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: diag(6091, ts.DiagnosticCategory.Message, "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", "'paths' option is specified, looking for a pattern to match module name '{0}'."),
        Module_name_0_matched_pattern_1: diag(6092, ts.DiagnosticCategory.Message, "Module_name_0_matched_pattern_1_6092", "Module name '{0}', matched pattern '{1}'."),
        Trying_substitution_0_candidate_module_location_Colon_1: diag(6093, ts.DiagnosticCategory.Message, "Trying_substitution_0_candidate_module_location_Colon_1_6093", "Trying substitution '{0}', candidate module location: '{1}'."),
        Resolving_module_name_0_relative_to_base_url_1_2: diag(6094, ts.DiagnosticCategory.Message, "Resolving_module_name_0_relative_to_base_url_1_2_6094", "Resolving module name '{0}' relative to base url '{1}' - '{2}'."),
        Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1: diag(6095, ts.DiagnosticCategory.Message, "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095", "Loading module as file / folder, candidate module location '{0}', target file type '{1}'."),
        File_0_does_not_exist: diag(6096, ts.DiagnosticCategory.Message, "File_0_does_not_exist_6096", "File '{0}' does not exist."),
        File_0_exist_use_it_as_a_name_resolution_result: diag(6097, ts.DiagnosticCategory.Message, "File_0_exist_use_it_as_a_name_resolution_result_6097", "File '{0}' exist - use it as a name resolution result."),
        Loading_module_0_from_node_modules_folder_target_file_type_1: diag(6098, ts.DiagnosticCategory.Message, "Loading_module_0_from_node_modules_folder_target_file_type_1_6098", "Loading module '{0}' from 'node_modules' folder, target file type '{1}'."),
        Found_package_json_at_0: diag(6099, ts.DiagnosticCategory.Message, "Found_package_json_at_0_6099", "Found 'package.json' at '{0}'."),
        package_json_does_not_have_a_0_field: diag(6100, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_0_field_6100", "'package.json' does not have a '{0}' field."),
        package_json_has_0_field_1_that_references_2: diag(6101, ts.DiagnosticCategory.Message, "package_json_has_0_field_1_that_references_2_6101", "'package.json' has '{0}' field '{1}' that references '{2}'."),
        Allow_javascript_files_to_be_compiled: diag(6102, ts.DiagnosticCategory.Message, "Allow_javascript_files_to_be_compiled_6102", "Allow javascript files to be compiled."),
        Option_0_should_have_array_of_strings_as_a_value: diag(6103, ts.DiagnosticCategory.Error, "Option_0_should_have_array_of_strings_as_a_value_6103", "Option '{0}' should have array of strings as a value."),
        Checking_if_0_is_the_longest_matching_prefix_for_1_2: diag(6104, ts.DiagnosticCategory.Message, "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."),
        Expected_type_of_0_field_in_package_json_to_be_string_got_1: diag(6105, ts.DiagnosticCategory.Message, "Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105", "Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'."),
        baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1: diag(6106, ts.DiagnosticCategory.Message, "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."),
        rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0: diag(6107, ts.DiagnosticCategory.Message, "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", "'rootDirs' option is set, using it to resolve relative module name '{0}'."),
        Longest_matching_prefix_for_0_is_1: diag(6108, ts.DiagnosticCategory.Message, "Longest_matching_prefix_for_0_is_1_6108", "Longest matching prefix for '{0}' is '{1}'."),
        Loading_0_from_the_root_dir_1_candidate_location_2: diag(6109, ts.DiagnosticCategory.Message, "Loading_0_from_the_root_dir_1_candidate_location_2_6109", "Loading '{0}' from the root dir '{1}', candidate location '{2}'."),
        Trying_other_entries_in_rootDirs: diag(6110, ts.DiagnosticCategory.Message, "Trying_other_entries_in_rootDirs_6110", "Trying other entries in 'rootDirs'."),
        Module_resolution_using_rootDirs_has_failed: diag(6111, ts.DiagnosticCategory.Message, "Module_resolution_using_rootDirs_has_failed_6111", "Module resolution using 'rootDirs' has failed."),
        Do_not_emit_use_strict_directives_in_module_output: diag(6112, ts.DiagnosticCategory.Message, "Do_not_emit_use_strict_directives_in_module_output_6112", "Do not emit 'use strict' directives in module output."),
        Enable_strict_null_checks: diag(6113, ts.DiagnosticCategory.Message, "Enable_strict_null_checks_6113", "Enable strict null checks."),
        Unknown_option_excludes_Did_you_mean_exclude: diag(6114, ts.DiagnosticCategory.Error, "Unknown_option_excludes_Did_you_mean_exclude_6114", "Unknown option 'excludes'. Did you mean 'exclude'?"),
        Raise_error_on_this_expressions_with_an_implied_any_type: diag(6115, ts.DiagnosticCategory.Message, "Raise_error_on_this_expressions_with_an_implied_any_type_6115", "Raise error on 'this' expressions with an implied 'any' type."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_2: diag(6116, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"),
        Resolving_using_primary_search_paths: diag(6117, ts.DiagnosticCategory.Message, "Resolving_using_primary_search_paths_6117", "Resolving using primary search paths..."),
        Resolving_from_node_modules_folder: diag(6118, ts.DiagnosticCategory.Message, "Resolving_from_node_modules_folder_6118", "Resolving from node_modules folder..."),
        Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: diag(6119, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"),
        Type_reference_directive_0_was_not_resolved: diag(6120, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_not_resolved_6120", "======== Type reference directive '{0}' was not resolved. ========"),
        Resolving_with_primary_search_path_0: diag(6121, ts.DiagnosticCategory.Message, "Resolving_with_primary_search_path_0_6121", "Resolving with primary search path '{0}'."),
        Root_directory_cannot_be_determined_skipping_primary_search_paths: diag(6122, ts.DiagnosticCategory.Message, "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", "Root directory cannot be determined, skipping primary search paths."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: diag(6123, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"),
        Type_declaration_files_to_be_included_in_compilation: diag(6124, ts.DiagnosticCategory.Message, "Type_declaration_files_to_be_included_in_compilation_6124", "Type declaration files to be included in compilation."),
        Looking_up_in_node_modules_folder_initial_location_0: diag(6125, ts.DiagnosticCategory.Message, "Looking_up_in_node_modules_folder_initial_location_0_6125", "Looking up in 'node_modules' folder, initial location '{0}'."),
        Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder: diag(6126, ts.DiagnosticCategory.Message, "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1: diag(6127, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: diag(6128, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"),
        Resolving_real_path_for_0_result_1: diag(6130, ts.DiagnosticCategory.Message, "Resolving_real_path_for_0_result_1_6130", "Resolving real path for '{0}', result '{1}'."),
        Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: diag(6131, ts.DiagnosticCategory.Error, "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."),
        File_name_0_has_a_1_extension_stripping_it: diag(6132, ts.DiagnosticCategory.Message, "File_name_0_has_a_1_extension_stripping_it_6132", "File name '{0}' has a '{1}' extension - stripping it."),
        _0_is_declared_but_its_value_is_never_read: diag(6133, ts.DiagnosticCategory.Error, "_0_is_declared_but_its_value_is_never_read_6133", "'{0}' is declared but its value is never read."),
        Report_errors_on_unused_locals: diag(6134, ts.DiagnosticCategory.Message, "Report_errors_on_unused_locals_6134", "Report errors on unused locals."),
        Report_errors_on_unused_parameters: diag(6135, ts.DiagnosticCategory.Message, "Report_errors_on_unused_parameters_6135", "Report errors on unused parameters."),
        The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: diag(6136, ts.DiagnosticCategory.Message, "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", "The maximum dependency depth to search under node_modules and load JavaScript files."),
        Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1: diag(6137, ts.DiagnosticCategory.Error, "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."),
        Property_0_is_declared_but_its_value_is_never_read: diag(6138, ts.DiagnosticCategory.Error, "Property_0_is_declared_but_its_value_is_never_read_6138", "Property '{0}' is declared but its value is never read."),
        Import_emit_helpers_from_tslib: diag(6139, ts.DiagnosticCategory.Message, "Import_emit_helpers_from_tslib_6139", "Import emit helpers from 'tslib'."),
        Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2: diag(6140, ts.DiagnosticCategory.Error, "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."),
        Parse_in_strict_mode_and_emit_use_strict_for_each_source_file: diag(6141, ts.DiagnosticCategory.Message, "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", "Parse in strict mode and emit \"use strict\" for each source file."),
        Module_0_was_resolved_to_1_but_jsx_is_not_set: diag(6142, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", "Module '{0}' was resolved to '{1}', but '--jsx' is not set."),
        Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1: diag(6144, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", "Module '{0}' was resolved as locally declared ambient module in file '{1}'."),
        Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified: diag(6145, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145", "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified."),
        Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h: diag(6146, ts.DiagnosticCategory.Message, "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."),
        Resolution_for_module_0_was_found_in_cache: diag(6147, ts.DiagnosticCategory.Message, "Resolution_for_module_0_was_found_in_cache_6147", "Resolution for module '{0}' was found in cache."),
        Directory_0_does_not_exist_skipping_all_lookups_in_it: diag(6148, ts.DiagnosticCategory.Message, "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", "Directory '{0}' does not exist, skipping all lookups in it."),
        Show_diagnostic_information: diag(6149, ts.DiagnosticCategory.Message, "Show_diagnostic_information_6149", "Show diagnostic information."),
        Show_verbose_diagnostic_information: diag(6150, ts.DiagnosticCategory.Message, "Show_verbose_diagnostic_information_6150", "Show verbose diagnostic information."),
        Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file: diag(6151, ts.DiagnosticCategory.Message, "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", "Emit a single file with source maps instead of having a separate file."),
        Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set: diag(6152, ts.DiagnosticCategory.Message, "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."),
        Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule: diag(6153, ts.DiagnosticCategory.Message, "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", "Transpile each file as a separate module (similar to 'ts.transpileModule')."),
        Print_names_of_generated_files_part_of_the_compilation: diag(6154, ts.DiagnosticCategory.Message, "Print_names_of_generated_files_part_of_the_compilation_6154", "Print names of generated files part of the compilation."),
        Print_names_of_files_part_of_the_compilation: diag(6155, ts.DiagnosticCategory.Message, "Print_names_of_files_part_of_the_compilation_6155", "Print names of files part of the compilation."),
        The_locale_used_when_displaying_messages_to_the_user_e_g_en_us: diag(6156, ts.DiagnosticCategory.Message, "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", "The locale used when displaying messages to the user (e.g. 'en-us')"),
        Do_not_generate_custom_helper_functions_like_extends_in_compiled_output: diag(6157, ts.DiagnosticCategory.Message, "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", "Do not generate custom helper functions like '__extends' in compiled output."),
        Do_not_include_the_default_library_file_lib_d_ts: diag(6158, ts.DiagnosticCategory.Message, "Do_not_include_the_default_library_file_lib_d_ts_6158", "Do not include the default library file (lib.d.ts)."),
        Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files: diag(6159, ts.DiagnosticCategory.Message, "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", "Do not add triple-slash references or imported modules to the list of compiled files."),
        Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files: diag(6160, ts.DiagnosticCategory.Message, "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."),
        List_of_folders_to_include_type_definitions_from: diag(6161, ts.DiagnosticCategory.Message, "List_of_folders_to_include_type_definitions_from_6161", "List of folders to include type definitions from."),
        Disable_size_limitations_on_JavaScript_projects: diag(6162, ts.DiagnosticCategory.Message, "Disable_size_limitations_on_JavaScript_projects_6162", "Disable size limitations on JavaScript projects."),
        The_character_set_of_the_input_files: diag(6163, ts.DiagnosticCategory.Message, "The_character_set_of_the_input_files_6163", "The character set of the input files."),
        Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files: diag(6164, ts.DiagnosticCategory.Message, "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164", "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."),
        Do_not_truncate_error_messages: diag(6165, ts.DiagnosticCategory.Message, "Do_not_truncate_error_messages_6165", "Do not truncate error messages."),
        Output_directory_for_generated_declaration_files: diag(6166, ts.DiagnosticCategory.Message, "Output_directory_for_generated_declaration_files_6166", "Output directory for generated declaration files."),
        A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl: diag(6167, ts.DiagnosticCategory.Message, "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."),
        List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime: diag(6168, ts.DiagnosticCategory.Message, "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", "List of root folders whose combined content represents the structure of the project at runtime."),
        Show_all_compiler_options: diag(6169, ts.DiagnosticCategory.Message, "Show_all_compiler_options_6169", "Show all compiler options."),
        Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file: diag(6170, ts.DiagnosticCategory.Message, "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"),
        Command_line_Options: diag(6171, ts.DiagnosticCategory.Message, "Command_line_Options_6171", "Command-line Options"),
        Basic_Options: diag(6172, ts.DiagnosticCategory.Message, "Basic_Options_6172", "Basic Options"),
        Strict_Type_Checking_Options: diag(6173, ts.DiagnosticCategory.Message, "Strict_Type_Checking_Options_6173", "Strict Type-Checking Options"),
        Module_Resolution_Options: diag(6174, ts.DiagnosticCategory.Message, "Module_Resolution_Options_6174", "Module Resolution Options"),
        Source_Map_Options: diag(6175, ts.DiagnosticCategory.Message, "Source_Map_Options_6175", "Source Map Options"),
        Additional_Checks: diag(6176, ts.DiagnosticCategory.Message, "Additional_Checks_6176", "Additional Checks"),
        Experimental_Options: diag(6177, ts.DiagnosticCategory.Message, "Experimental_Options_6177", "Experimental Options"),
        Advanced_Options: diag(6178, ts.DiagnosticCategory.Message, "Advanced_Options_6178", "Advanced Options"),
        Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3: diag(6179, ts.DiagnosticCategory.Message, "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179", "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'."),
        Enable_all_strict_type_checking_options: diag(6180, ts.DiagnosticCategory.Message, "Enable_all_strict_type_checking_options_6180", "Enable all strict type-checking options."),
        List_of_language_service_plugins: diag(6181, ts.DiagnosticCategory.Message, "List_of_language_service_plugins_6181", "List of language service plugins."),
        Scoped_package_detected_looking_in_0: diag(6182, ts.DiagnosticCategory.Message, "Scoped_package_detected_looking_in_0_6182", "Scoped package detected, looking in '{0}'"),
        Reusing_resolution_of_module_0_to_file_1_from_old_program: diag(6183, ts.DiagnosticCategory.Message, "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183", "Reusing resolution of module '{0}' to file '{1}' from old program."),
        Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program: diag(6184, ts.DiagnosticCategory.Message, "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184", "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program."),
        Disable_strict_checking_of_generic_signatures_in_function_types: diag(6185, ts.DiagnosticCategory.Message, "Disable_strict_checking_of_generic_signatures_in_function_types_6185", "Disable strict checking of generic signatures in function types."),
        Enable_strict_checking_of_function_types: diag(6186, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_function_types_6186", "Enable strict checking of function types."),
        Variable_0_implicitly_has_an_1_type: diag(7005, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_an_1_type_7005", "Variable '{0}' implicitly has an '{1}' type."),
        Parameter_0_implicitly_has_an_1_type: diag(7006, ts.DiagnosticCategory.Error, "Parameter_0_implicitly_has_an_1_type_7006", "Parameter '{0}' implicitly has an '{1}' type."),
        Member_0_implicitly_has_an_1_type: diag(7008, ts.DiagnosticCategory.Error, "Member_0_implicitly_has_an_1_type_7008", "Member '{0}' implicitly has an '{1}' type."),
        new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: diag(7009, ts.DiagnosticCategory.Error, "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."),
        _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: diag(7010, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."),
        Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7011, ts.DiagnosticCategory.Error, "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7013, ts.DiagnosticCategory.Error, "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number: diag(7015, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", "Element implicitly has an 'any' type because index expression is not of type 'number'."),
        Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type: diag(7016, ts.DiagnosticCategory.Error, "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature: diag(7017, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", "Element implicitly has an 'any' type because type '{0}' has no index signature."),
        Object_literal_s_property_0_implicitly_has_an_1_type: diag(7018, ts.DiagnosticCategory.Error, "Object_literal_s_property_0_implicitly_has_an_1_type_7018", "Object literal's property '{0}' implicitly has an '{1}' type."),
        Rest_parameter_0_implicitly_has_an_any_type: diag(7019, ts.DiagnosticCategory.Error, "Rest_parameter_0_implicitly_has_an_any_type_7019", "Rest parameter '{0}' implicitly has an 'any[]' type."),
        Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7020, ts.DiagnosticCategory.Error, "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: diag(7022, ts.DiagnosticCategory.Error, "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."),
        _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7023, ts.DiagnosticCategory.Error, "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7024, ts.DiagnosticCategory.Error, "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: diag(7025, ts.DiagnosticCategory.Error, "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025", "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type."),
        JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: diag(7026, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."),
        Unreachable_code_detected: diag(7027, ts.DiagnosticCategory.Error, "Unreachable_code_detected_7027", "Unreachable code detected."),
        Unused_label: diag(7028, ts.DiagnosticCategory.Error, "Unused_label_7028", "Unused label."),
        Fallthrough_case_in_switch: diag(7029, ts.DiagnosticCategory.Error, "Fallthrough_case_in_switch_7029", "Fallthrough case in switch."),
        Not_all_code_paths_return_a_value: diag(7030, ts.DiagnosticCategory.Error, "Not_all_code_paths_return_a_value_7030", "Not all code paths return a value."),
        Binding_element_0_implicitly_has_an_1_type: diag(7031, ts.DiagnosticCategory.Error, "Binding_element_0_implicitly_has_an_1_type_7031", "Binding element '{0}' implicitly has an '{1}' type."),
        Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation: diag(7032, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."),
        Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation: diag(7033, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."),
        Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined: diag(7034, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."),
        Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0: diag(7035, ts.DiagnosticCategory.Error, "Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035", "Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"),
        Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0: diag(7036, ts.DiagnosticCategory.Error, "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", "Dynamic import's specifier must be of type 'string', but here has type '{0}'."),
        You_cannot_rename_this_element: diag(8000, ts.DiagnosticCategory.Error, "You_cannot_rename_this_element_8000", "You cannot rename this element."),
        You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: diag(8001, ts.DiagnosticCategory.Error, "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", "You cannot rename elements that are defined in the standard TypeScript library."),
        import_can_only_be_used_in_a_ts_file: diag(8002, ts.DiagnosticCategory.Error, "import_can_only_be_used_in_a_ts_file_8002", "'import ... =' can only be used in a .ts file."),
        export_can_only_be_used_in_a_ts_file: diag(8003, ts.DiagnosticCategory.Error, "export_can_only_be_used_in_a_ts_file_8003", "'export=' can only be used in a .ts file."),
        type_parameter_declarations_can_only_be_used_in_a_ts_file: diag(8004, ts.DiagnosticCategory.Error, "type_parameter_declarations_can_only_be_used_in_a_ts_file_8004", "'type parameter declarations' can only be used in a .ts file."),
        implements_clauses_can_only_be_used_in_a_ts_file: diag(8005, ts.DiagnosticCategory.Error, "implements_clauses_can_only_be_used_in_a_ts_file_8005", "'implements clauses' can only be used in a .ts file."),
        interface_declarations_can_only_be_used_in_a_ts_file: diag(8006, ts.DiagnosticCategory.Error, "interface_declarations_can_only_be_used_in_a_ts_file_8006", "'interface declarations' can only be used in a .ts file."),
        module_declarations_can_only_be_used_in_a_ts_file: diag(8007, ts.DiagnosticCategory.Error, "module_declarations_can_only_be_used_in_a_ts_file_8007", "'module declarations' can only be used in a .ts file."),
        type_aliases_can_only_be_used_in_a_ts_file: diag(8008, ts.DiagnosticCategory.Error, "type_aliases_can_only_be_used_in_a_ts_file_8008", "'type aliases' can only be used in a .ts file."),
        _0_can_only_be_used_in_a_ts_file: diag(8009, ts.DiagnosticCategory.Error, "_0_can_only_be_used_in_a_ts_file_8009", "'{0}' can only be used in a .ts file."),
        types_can_only_be_used_in_a_ts_file: diag(8010, ts.DiagnosticCategory.Error, "types_can_only_be_used_in_a_ts_file_8010", "'types' can only be used in a .ts file."),
        type_arguments_can_only_be_used_in_a_ts_file: diag(8011, ts.DiagnosticCategory.Error, "type_arguments_can_only_be_used_in_a_ts_file_8011", "'type arguments' can only be used in a .ts file."),
        parameter_modifiers_can_only_be_used_in_a_ts_file: diag(8012, ts.DiagnosticCategory.Error, "parameter_modifiers_can_only_be_used_in_a_ts_file_8012", "'parameter modifiers' can only be used in a .ts file."),
        non_null_assertions_can_only_be_used_in_a_ts_file: diag(8013, ts.DiagnosticCategory.Error, "non_null_assertions_can_only_be_used_in_a_ts_file_8013", "'non-null assertions' can only be used in a .ts file."),
        enum_declarations_can_only_be_used_in_a_ts_file: diag(8015, ts.DiagnosticCategory.Error, "enum_declarations_can_only_be_used_in_a_ts_file_8015", "'enum declarations' can only be used in a .ts file."),
        type_assertion_expressions_can_only_be_used_in_a_ts_file: diag(8016, ts.DiagnosticCategory.Error, "type_assertion_expressions_can_only_be_used_in_a_ts_file_8016", "'type assertion expressions' can only be used in a .ts file."),
        Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0: diag(8017, ts.DiagnosticCategory.Error, "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017", "Octal literal types must use ES2015 syntax. Use the syntax '{0}'."),
        Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0: diag(8018, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018", "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'."),
        Report_errors_in_js_files: diag(8019, ts.DiagnosticCategory.Message, "Report_errors_in_js_files_8019", "Report errors in .js files."),
        JSDoc_types_can_only_be_used_inside_documentation_comments: diag(8020, ts.DiagnosticCategory.Error, "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", "JSDoc types can only be used inside documentation comments."),
        JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags: diag(8021, ts.DiagnosticCategory.Error, "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."),
        JSDoc_0_is_not_attached_to_a_class: diag(8022, ts.DiagnosticCategory.Error, "JSDoc_0_is_not_attached_to_a_class_8022", "JSDoc '@{0}' is not attached to a class."),
        JSDoc_0_1_does_not_match_the_extends_2_clause: diag(8023, ts.DiagnosticCategory.Error, "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name: diag(8024, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."),
        Class_declarations_cannot_have_more_than_one_augments_or_extends_tag: diag(8025, ts.DiagnosticCategory.Error, "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", "Class declarations cannot have more than one `@augments` or `@extends` tag."),
        Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."),
        class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."),
        Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."),
        JSX_attributes_must_only_be_assigned_a_non_empty_expression: diag(17000, ts.DiagnosticCategory.Error, "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", "JSX attributes must only be assigned a non-empty 'expression'."),
        JSX_elements_cannot_have_multiple_attributes_with_the_same_name: diag(17001, ts.DiagnosticCategory.Error, "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", "JSX elements cannot have multiple attributes with the same name."),
        Expected_corresponding_JSX_closing_tag_for_0: diag(17002, ts.DiagnosticCategory.Error, "Expected_corresponding_JSX_closing_tag_for_0_17002", "Expected corresponding JSX closing tag for '{0}'."),
        JSX_attribute_expected: diag(17003, ts.DiagnosticCategory.Error, "JSX_attribute_expected_17003", "JSX attribute expected."),
        Cannot_use_JSX_unless_the_jsx_flag_is_provided: diag(17004, ts.DiagnosticCategory.Error, "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", "Cannot use JSX unless the '--jsx' flag is provided."),
        A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: diag(17005, ts.DiagnosticCategory.Error, "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", "A constructor cannot contain a 'super' call when its class extends 'null'."),
        An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17006, ts.DiagnosticCategory.Error, "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17007, ts.DiagnosticCategory.Error, "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        JSX_element_0_has_no_corresponding_closing_tag: diag(17008, ts.DiagnosticCategory.Error, "JSX_element_0_has_no_corresponding_closing_tag_17008", "JSX element '{0}' has no corresponding closing tag."),
        super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: diag(17009, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", "'super' must be called before accessing 'this' in the constructor of a derived class."),
        Unknown_type_acquisition_option_0: diag(17010, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_17010", "Unknown type acquisition option '{0}'."),
        super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class: diag(17011, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", "'super' must be called before accessing a property of 'super' in the constructor of a derived class."),
        _0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2: diag(17012, ts.DiagnosticCategory.Error, "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"),
        Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor: diag(17013, ts.DiagnosticCategory.Error, "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."),
        Circularity_detected_while_resolving_configuration_Colon_0: diag(18000, ts.DiagnosticCategory.Error, "Circularity_detected_while_resolving_configuration_Colon_0_18000", "Circularity detected while resolving configuration: {0}"),
        A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not: diag(18001, ts.DiagnosticCategory.Error, "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001", "A path in an 'extends' option must be relative or rooted, but '{0}' is not."),
        The_files_list_in_config_file_0_is_empty: diag(18002, ts.DiagnosticCategory.Error, "The_files_list_in_config_file_0_is_empty_18002", "The 'files' list in config file '{0}' is empty."),
        No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2: diag(18003, ts.DiagnosticCategory.Error, "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."),
        Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call."),
        Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor."),
        Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'."),
        Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'."),
        Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'."),
        Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class."),
        Add_this_to_unresolved_variable: diag(90008, ts.DiagnosticCategory.Message, "Add_this_to_unresolved_variable_90008", "Add 'this.' to unresolved variable."),
        Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig: diag(90009, ts.DiagnosticCategory.Error, "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__90009", "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."),
        Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated: diag(90010, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_90010", "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."),
        Import_0_from_1: diag(90013, ts.DiagnosticCategory.Message, "Import_0_from_1_90013", "Import '{0}' from \"{1}\"."),
        Change_0_to_1: diag(90014, ts.DiagnosticCategory.Message, "Change_0_to_1_90014", "Change '{0}' to '{1}'."),
        Add_0_to_existing_import_declaration_from_1: diag(90015, ts.DiagnosticCategory.Message, "Add_0_to_existing_import_declaration_from_1_90015", "Add '{0}' to existing import declaration from \"{1}\"."),
        Declare_property_0: diag(90016, ts.DiagnosticCategory.Message, "Declare_property_0_90016", "Declare property '{0}'."),
        Add_index_signature_for_property_0: diag(90017, ts.DiagnosticCategory.Message, "Add_index_signature_for_property_0_90017", "Add index signature for property '{0}'."),
        Disable_checking_for_this_file: diag(90018, ts.DiagnosticCategory.Message, "Disable_checking_for_this_file_90018", "Disable checking for this file."),
        Ignore_this_error_message: diag(90019, ts.DiagnosticCategory.Message, "Ignore_this_error_message_90019", "Ignore this error message."),
        Initialize_property_0_in_the_constructor: diag(90020, ts.DiagnosticCategory.Message, "Initialize_property_0_in_the_constructor_90020", "Initialize property '{0}' in the constructor."),
        Initialize_static_property_0: diag(90021, ts.DiagnosticCategory.Message, "Initialize_static_property_0_90021", "Initialize static property '{0}'."),
        Change_spelling_to_0: diag(90022, ts.DiagnosticCategory.Message, "Change_spelling_to_0_90022", "Change spelling to '{0}'."),
        Declare_method_0: diag(90023, ts.DiagnosticCategory.Message, "Declare_method_0_90023", "Declare method '{0}'."),
        Declare_static_method_0: diag(90024, ts.DiagnosticCategory.Message, "Declare_static_method_0_90024", "Declare static method '{0}'."),
        Prefix_0_with_an_underscore: diag(90025, ts.DiagnosticCategory.Message, "Prefix_0_with_an_underscore_90025", "Prefix '{0}' with an underscore."),
        Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."),
        Declare_static_property_0: diag(90027, ts.DiagnosticCategory.Message, "Declare_static_property_0_90027", "Declare static property '{0}'."),
        Call_decorator_expression: diag(90028, ts.DiagnosticCategory.Message, "Call_decorator_expression_90028", "Call decorator expression."),
        Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"),
        Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"),
        Extract_symbol: diag(95003, ts.DiagnosticCategory.Message, "Extract_symbol_95003", "Extract symbol"),
        Extract_to_0_in_1: diag(95004, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_95004", "Extract to {0} in {1}"),
        Extract_function: diag(95005, ts.DiagnosticCategory.Message, "Extract_function_95005", "Extract function"),
        Extract_constant: diag(95006, ts.DiagnosticCategory.Message, "Extract_constant_95006", "Extract constant"),
        Extract_to_0_in_enclosing_scope: diag(95007, ts.DiagnosticCategory.Message, "Extract_to_0_in_enclosing_scope_95007", "Extract to {0} in enclosing scope"),
        Extract_to_0_in_1_scope: diag(95008, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_scope_95008", "Extract to {0} in {1} scope"),
        Annotate_with_type_from_JSDoc: diag(95009, ts.DiagnosticCategory.Message, "Annotate_with_type_from_JSDoc_95009", "Annotate with type from JSDoc"),
        Annotate_with_types_from_JSDoc: diag(95010, ts.DiagnosticCategory.Message, "Annotate_with_types_from_JSDoc_95010", "Annotate with types from JSDoc"),
        Infer_type_of_0_from_usage: diag(95011, ts.DiagnosticCategory.Message, "Infer_type_of_0_from_usage_95011", "Infer type of '{0}' from usage."),
        Infer_parameter_types_from_usage: diag(95012, ts.DiagnosticCategory.Message, "Infer_parameter_types_from_usage_95012", "Infer parameter types from usage."),
    };
})(ts || (ts = {}));
/// <reference path="core.ts"/>
/// <reference path="diagnosticInformationMap.generated.ts"/>
var ts;
(function (ts) {
    /* @internal */
    function tokenIsIdentifierOrKeyword(token) {
        return token >= 71 /* Identifier */;
    }
    ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword;
    var textToToken = ts.createMapFromTemplate({
        "abstract": 117 /* AbstractKeyword */,
        "any": 119 /* AnyKeyword */,
        "as": 118 /* AsKeyword */,
        "boolean": 122 /* BooleanKeyword */,
        "break": 72 /* BreakKeyword */,
        "case": 73 /* CaseKeyword */,
        "catch": 74 /* CatchKeyword */,
        "class": 75 /* ClassKeyword */,
        "continue": 77 /* ContinueKeyword */,
        "const": 76 /* ConstKeyword */,
        "constructor": 123 /* ConstructorKeyword */,
        "debugger": 78 /* DebuggerKeyword */,
        "declare": 124 /* DeclareKeyword */,
        "default": 79 /* DefaultKeyword */,
        "delete": 80 /* DeleteKeyword */,
        "do": 81 /* DoKeyword */,
        "else": 82 /* ElseKeyword */,
        "enum": 83 /* EnumKeyword */,
        "export": 84 /* ExportKeyword */,
        "extends": 85 /* ExtendsKeyword */,
        "false": 86 /* FalseKeyword */,
        "finally": 87 /* FinallyKeyword */,
        "for": 88 /* ForKeyword */,
        "from": 140 /* FromKeyword */,
        "function": 89 /* FunctionKeyword */,
        "get": 125 /* GetKeyword */,
        "if": 90 /* IfKeyword */,
        "implements": 108 /* ImplementsKeyword */,
        "import": 91 /* ImportKeyword */,
        "in": 92 /* InKeyword */,
        "instanceof": 93 /* InstanceOfKeyword */,
        "interface": 109 /* InterfaceKeyword */,
        "is": 126 /* IsKeyword */,
        "keyof": 127 /* KeyOfKeyword */,
        "let": 110 /* LetKeyword */,
        "module": 128 /* ModuleKeyword */,
        "namespace": 129 /* NamespaceKeyword */,
        "never": 130 /* NeverKeyword */,
        "new": 94 /* NewKeyword */,
        "null": 95 /* NullKeyword */,
        "number": 133 /* NumberKeyword */,
        "object": 134 /* ObjectKeyword */,
        "package": 111 /* PackageKeyword */,
        "private": 112 /* PrivateKeyword */,
        "protected": 113 /* ProtectedKeyword */,
        "public": 114 /* PublicKeyword */,
        "readonly": 131 /* ReadonlyKeyword */,
        "require": 132 /* RequireKeyword */,
        "global": 141 /* GlobalKeyword */,
        "return": 96 /* ReturnKeyword */,
        "set": 135 /* SetKeyword */,
        "static": 115 /* StaticKeyword */,
        "string": 136 /* StringKeyword */,
        "super": 97 /* SuperKeyword */,
        "switch": 98 /* SwitchKeyword */,
        "symbol": 137 /* SymbolKeyword */,
        "this": 99 /* ThisKeyword */,
        "throw": 100 /* ThrowKeyword */,
        "true": 101 /* TrueKeyword */,
        "try": 102 /* TryKeyword */,
        "type": 138 /* TypeKeyword */,
        "typeof": 103 /* TypeOfKeyword */,
        "undefined": 139 /* UndefinedKeyword */,
        "var": 104 /* VarKeyword */,
        "void": 105 /* VoidKeyword */,
        "while": 106 /* WhileKeyword */,
        "with": 107 /* WithKeyword */,
        "yield": 116 /* YieldKeyword */,
        "async": 120 /* AsyncKeyword */,
        "await": 121 /* AwaitKeyword */,
        "of": 142 /* OfKeyword */,
        "{": 17 /* OpenBraceToken */,
        "}": 18 /* CloseBraceToken */,
        "(": 19 /* OpenParenToken */,
        ")": 20 /* CloseParenToken */,
        "[": 21 /* OpenBracketToken */,
        "]": 22 /* CloseBracketToken */,
        ".": 23 /* DotToken */,
        "...": 24 /* DotDotDotToken */,
        ";": 25 /* SemicolonToken */,
        ",": 26 /* CommaToken */,
        "<": 27 /* LessThanToken */,
        ">": 29 /* GreaterThanToken */,
        "<=": 30 /* LessThanEqualsToken */,
        ">=": 31 /* GreaterThanEqualsToken */,
        "==": 32 /* EqualsEqualsToken */,
        "!=": 33 /* ExclamationEqualsToken */,
        "===": 34 /* EqualsEqualsEqualsToken */,
        "!==": 35 /* ExclamationEqualsEqualsToken */,
        "=>": 36 /* EqualsGreaterThanToken */,
        "+": 37 /* PlusToken */,
        "-": 38 /* MinusToken */,
        "**": 40 /* AsteriskAsteriskToken */,
        "*": 39 /* AsteriskToken */,
        "/": 41 /* SlashToken */,
        "%": 42 /* PercentToken */,
        "++": 43 /* PlusPlusToken */,
        "--": 44 /* MinusMinusToken */,
        "<<": 45 /* LessThanLessThanToken */,
        "</": 28 /* LessThanSlashToken */,
        ">>": 46 /* GreaterThanGreaterThanToken */,
        ">>>": 47 /* GreaterThanGreaterThanGreaterThanToken */,
        "&": 48 /* AmpersandToken */,
        "|": 49 /* BarToken */,
        "^": 50 /* CaretToken */,
        "!": 51 /* ExclamationToken */,
        "~": 52 /* TildeToken */,
        "&&": 53 /* AmpersandAmpersandToken */,
        "||": 54 /* BarBarToken */,
        "?": 55 /* QuestionToken */,
        ":": 56 /* ColonToken */,
        "=": 58 /* EqualsToken */,
        "+=": 59 /* PlusEqualsToken */,
        "-=": 60 /* MinusEqualsToken */,
        "*=": 61 /* AsteriskEqualsToken */,
        "**=": 62 /* AsteriskAsteriskEqualsToken */,
        "/=": 63 /* SlashEqualsToken */,
        "%=": 64 /* PercentEqualsToken */,
        "<<=": 65 /* LessThanLessThanEqualsToken */,
        ">>=": 66 /* GreaterThanGreaterThanEqualsToken */,
        ">>>=": 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */,
        "&=": 68 /* AmpersandEqualsToken */,
        "|=": 69 /* BarEqualsToken */,
        "^=": 70 /* CaretEqualsToken */,
        "@": 57 /* AtToken */,
    });
    /*
        As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
        IdentifierStart ::
            Can contain Unicode 3.0.0  categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart :: =
            Can contain IdentifierStart + Unicode 3.0.0  categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd), or
            Connector punctuation (Pc).

        Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at:
        http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
    */
    var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    /*
        As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
        IdentifierStart ::
            Can contain Unicode 6.2  categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart ::
            Can contain IdentifierStart + Unicode 6.2  categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd),
            Connector punctuation (Pc),
            <ZWNJ>, or
            <ZWJ>.

        Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at:
        http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt
    */
    var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    function lookupInUnicodeMap(code, map) {
        // Bail out quickly if it couldn't possibly be in the map.
        if (code < map[0]) {
            return false;
        }
        // Perform binary search in one of the Unicode range maps
        var lo = 0;
        var hi = map.length;
        var mid;
        while (lo + 1 < hi) {
            mid = lo + (hi - lo) / 2;
            // mid has to be even to catch a range's beginning
            mid -= mid % 2;
            if (map[mid] <= code && code <= map[mid + 1]) {
                return true;
            }
            if (code < map[mid]) {
                hi = mid;
            }
            else {
                lo = mid + 2;
            }
        }
        return false;
    }
    /* @internal */ function isUnicodeIdentifierStart(code, languageVersion) {
        return languageVersion >= 1 /* ES5 */ ?
            lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
            lookupInUnicodeMap(code, unicodeES3IdentifierStart);
    }
    ts.isUnicodeIdentifierStart = isUnicodeIdentifierStart;
    function isUnicodeIdentifierPart(code, languageVersion) {
        return languageVersion >= 1 /* ES5 */ ?
            lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
            lookupInUnicodeMap(code, unicodeES3IdentifierPart);
    }
    function makeReverseMap(source) {
        var result = [];
        source.forEach(function (value, name) {
            result[value] = name;
        });
        return result;
    }
    var tokenStrings = makeReverseMap(textToToken);
    function tokenToString(t) {
        return tokenStrings[t];
    }
    ts.tokenToString = tokenToString;
    /* @internal */
    function stringToToken(s) {
        return textToToken.get(s);
    }
    ts.stringToToken = stringToToken;
    /* @internal */
    function computeLineStarts(text) {
        var result = new Array();
        var pos = 0;
        var lineStart = 0;
        while (pos < text.length) {
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    result.push(lineStart);
                    lineStart = pos;
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) {
                        result.push(lineStart);
                        lineStart = pos;
                    }
                    break;
            }
        }
        result.push(lineStart);
        return result;
    }
    ts.computeLineStarts = computeLineStarts;
    function getPositionOfLineAndCharacter(sourceFile, line, character) {
        return computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text);
    }
    ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
    /* @internal */
    function computePositionOfLineAndCharacter(lineStarts, line, character, debugText) {
        ts.Debug.assert(line >= 0 && line < lineStarts.length);
        var res = lineStarts[line] + character;
        if (line < lineStarts.length - 1) {
            ts.Debug.assert(res < lineStarts[line + 1]);
        }
        else if (debugText !== undefined) {
            ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
        }
        return res;
    }
    ts.computePositionOfLineAndCharacter = computePositionOfLineAndCharacter;
    /* @internal */
    function getLineStarts(sourceFile) {
        return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
    }
    ts.getLineStarts = getLineStarts;
    /* @internal */
    /**
     * We assume the first line starts at position 0 and 'position' is non-negative.
     */
    function computeLineAndCharacterOfPosition(lineStarts, position) {
        var lineNumber = ts.binarySearch(lineStarts, position);
        if (lineNumber < 0) {
            // If the actual position was not found,
            // the binary search returns the 2's-complement of the next line start
            // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
            // then the search will return -2.
            //
            // We want the index of the previous line start, so we subtract 1.
            // Review 2's-complement if this is confusing.
            lineNumber = ~lineNumber - 1;
            ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
        }
        return {
            line: lineNumber,
            character: position - lineStarts[lineNumber]
        };
    }
    ts.computeLineAndCharacterOfPosition = computeLineAndCharacterOfPosition;
    function getLineAndCharacterOfPosition(sourceFile, position) {
        return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
    }
    ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
    function isWhiteSpaceLike(ch) {
        return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
    }
    ts.isWhiteSpaceLike = isWhiteSpaceLike;
    /** Does not include line breaks. For that, see isWhiteSpaceLike. */
    function isWhiteSpaceSingleLine(ch) {
        // Note: nextLine is in the Zs space, and should be considered to be a whitespace.
        // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript.
        return ch === 32 /* space */ ||
            ch === 9 /* tab */ ||
            ch === 11 /* verticalTab */ ||
            ch === 12 /* formFeed */ ||
            ch === 160 /* nonBreakingSpace */ ||
            ch === 133 /* nextLine */ ||
            ch === 5760 /* ogham */ ||
            ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ ||
            ch === 8239 /* narrowNoBreakSpace */ ||
            ch === 8287 /* mathematicalSpace */ ||
            ch === 12288 /* ideographicSpace */ ||
            ch === 65279 /* byteOrderMark */;
    }
    ts.isWhiteSpaceSingleLine = isWhiteSpaceSingleLine;
    function isLineBreak(ch) {
        // ES5 7.3:
        // The ECMAScript line terminator characters are listed in Table 3.
        //     Table 3: Line Terminator Characters
        //     Code Unit Value     Name                    Formal Name
        //     \u000A              Line Feed               <LF>
        //     \u000D              Carriage Return         <CR>
        //     \u2028              Line separator          <LS>
        //     \u2029              Paragraph separator     <PS>
        // Only the characters in Table 3 are treated as line terminators. Other new line or line
        // breaking characters are treated as white space but not as line terminators.
        return ch === 10 /* lineFeed */ ||
            ch === 13 /* carriageReturn */ ||
            ch === 8232 /* lineSeparator */ ||
            ch === 8233 /* paragraphSeparator */;
    }
    ts.isLineBreak = isLineBreak;
    function isDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    /* @internal */
    function isOctalDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 55 /* _7 */;
    }
    ts.isOctalDigit = isOctalDigit;
    function couldStartTrivia(text, pos) {
        // Keep in sync with skipTrivia
        var ch = text.charCodeAt(pos);
        switch (ch) {
            case 13 /* carriageReturn */:
            case 10 /* lineFeed */:
            case 9 /* tab */:
            case 11 /* verticalTab */:
            case 12 /* formFeed */:
            case 32 /* space */:
            case 47 /* slash */:
            // starts of normal trivia
            case 60 /* lessThan */:
            case 124 /* bar */:
            case 61 /* equals */:
            case 62 /* greaterThan */:
                // Starts of conflict marker trivia
                return true;
            case 35 /* hash */:
                // Only if its the beginning can we have #! trivia
                return pos === 0;
            default:
                return ch > 127 /* maxAsciiCharacter */;
        }
    }
    ts.couldStartTrivia = couldStartTrivia;
    /* @internal */
    function skipTrivia(text, pos, stopAfterLineBreak, stopAtComments) {
        if (stopAtComments === void 0) { stopAtComments = false; }
        if (ts.positionIsSynthesized(pos)) {
            return pos;
        }
        // Keep in sync with couldStartTrivia
        while (true) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (stopAfterLineBreak) {
                        return pos;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    if (stopAtComments) {
                        break;
                    }
                    if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (isLineBreak(text.charCodeAt(pos))) {
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                pos += 2;
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    break;
                case 60 /* lessThan */:
                case 124 /* bar */:
                case 61 /* equals */:
                case 62 /* greaterThan */:
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos);
                        continue;
                    }
                    break;
                case 35 /* hash */:
                    if (pos === 0 && isShebangTrivia(text, pos)) {
                        pos = scanShebangTrivia(text, pos);
                        continue;
                    }
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        pos++;
                        continue;
                    }
                    break;
            }
            return pos;
        }
    }
    ts.skipTrivia = skipTrivia;
    // All conflict markers consist of the same character repeated seven times.  If it is
    // a <<<<<<< or >>>>>>> marker then it is also followed by a space.
    var mergeConflictMarkerLength = "<<<<<<<".length;
    function isConflictMarkerTrivia(text, pos) {
        ts.Debug.assert(pos >= 0);
        // Conflict markers must be at the start of a line.
        if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) {
            var ch = text.charCodeAt(pos);
            if ((pos + mergeConflictMarkerLength) < text.length) {
                for (var i = 0; i < mergeConflictMarkerLength; i++) {
                    if (text.charCodeAt(pos + i) !== ch) {
                        return false;
                    }
                }
                return ch === 61 /* equals */ ||
                    text.charCodeAt(pos + mergeConflictMarkerLength) === 32 /* space */;
            }
        }
        return false;
    }
    function scanConflictMarkerTrivia(text, pos, error) {
        if (error) {
            error(ts.Diagnostics.Merge_conflict_marker_encountered, mergeConflictMarkerLength);
        }
        var ch = text.charCodeAt(pos);
        var len = text.length;
        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
            while (pos < len && !isLineBreak(text.charCodeAt(pos))) {
                pos++;
            }
        }
        else {
            ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
            // Consume everything from the start of a ||||||| or ======= marker to the start
            // of the next ======= or >>>>>>> marker.
            while (pos < len) {
                var currentChar = text.charCodeAt(pos);
                if ((currentChar === 61 /* equals */ || currentChar === 62 /* greaterThan */) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
                    break;
                }
                pos++;
            }
        }
        return pos;
    }
    var shebangTriviaRegex = /^#!.*/;
    function isShebangTrivia(text, pos) {
        // Shebangs check must only be done at the start of the file
        ts.Debug.assert(pos === 0);
        return shebangTriviaRegex.test(text);
    }
    function scanShebangTrivia(text, pos) {
        var shebang = shebangTriviaRegex.exec(text)[0];
        pos = pos + shebang.length;
        return pos;
    }
    /**
     * Invokes a callback for each comment range following the provided position.
     *
     * Single-line comment ranges include the leading double-slash characters but not the ending
     * line break. Multi-line comment ranges include the leading slash-asterisk and trailing
     * asterisk-slash characters.
     *
     * @param reduce If true, accumulates the result of calling the callback in a fashion similar
     *      to reduceLeft. If false, iteration stops when the callback returns a truthy value.
     * @param text The source text to scan.
     * @param pos The position at which to start scanning.
     * @param trailing If false, whitespace is skipped until the first line break and comments
     *      between that location and the next token are returned. If true, comments occurring
     *      between the given position and the next line break are returned.
     * @param cb The callback to execute as each comment range is encountered.
     * @param state A state value to pass to each iteration of the callback.
     * @param initial An initial value to pass when accumulating results (when "reduce" is true).
     * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
     *      return value of the callback.
     */
    function iterateCommentRanges(reduce, text, pos, trailing, cb, state, initial) {
        var pendingPos;
        var pendingEnd;
        var pendingKind;
        var pendingHasTrailingNewLine;
        var hasPendingCommentRange = false;
        var collecting = trailing || pos === 0;
        var accumulator = initial;
        scan: while (pos >= 0 && pos < text.length) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (trailing) {
                        break scan;
                    }
                    collecting = true;
                    if (hasPendingCommentRange) {
                        pendingHasTrailingNewLine = true;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    var nextChar = text.charCodeAt(pos + 1);
                    var hasTrailingNewLine = false;
                    if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) {
                        var kind = nextChar === 47 /* slash */ ? 2 /* SingleLineCommentTrivia */ : 3 /* MultiLineCommentTrivia */;
                        var startPos = pos;
                        pos += 2;
                        if (nextChar === 47 /* slash */) {
                            while (pos < text.length) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    hasTrailingNewLine = true;
                                    break;
                                }
                                pos++;
                            }
                        }
                        else {
                            while (pos < text.length) {
                                if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    break;
                                }
                                pos++;
                            }
                        }
                        if (collecting) {
                            if (hasPendingCommentRange) {
                                accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
                                if (!reduce && accumulator) {
                                    // If we are not reducing and we have a truthy result, return it.
                                    return accumulator;
                                }
                                hasPendingCommentRange = false;
                            }
                            pendingPos = startPos;
                            pendingEnd = pos;
                            pendingKind = kind;
                            pendingHasTrailingNewLine = hasTrailingNewLine;
                            hasPendingCommentRange = true;
                        }
                        continue;
                    }
                    break scan;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        if (hasPendingCommentRange && isLineBreak(ch)) {
                            pendingHasTrailingNewLine = true;
                        }
                        pos++;
                        continue;
                    }
                    break scan;
            }
        }
        if (hasPendingCommentRange) {
            accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
        }
        return accumulator;
    }
    function forEachLeadingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
    }
    ts.forEachLeadingCommentRange = forEachLeadingCommentRange;
    function forEachTrailingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
    }
    ts.forEachTrailingCommentRange = forEachTrailingCommentRange;
    function reduceEachLeadingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
    }
    ts.reduceEachLeadingCommentRange = reduceEachLeadingCommentRange;
    function reduceEachTrailingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
    }
    ts.reduceEachTrailingCommentRange = reduceEachTrailingCommentRange;
    function appendCommentRange(pos, end, kind, hasTrailingNewLine, _state, comments) {
        if (!comments) {
            comments = [];
        }
        comments.push({ kind: kind, pos: pos, end: end, hasTrailingNewLine: hasTrailingNewLine });
        return comments;
    }
    function getLeadingCommentRanges(text, pos) {
        return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getLeadingCommentRanges = getLeadingCommentRanges;
    function getTrailingCommentRanges(text, pos) {
        return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getTrailingCommentRanges = getTrailingCommentRanges;
    /** Optionally, get the shebang */
    function getShebang(text) {
        var match = shebangTriviaRegex.exec(text);
        if (match) {
            return match[0];
        }
    }
    ts.getShebang = getShebang;
    function isIdentifierStart(ch, languageVersion) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch === 36 /* $ */ || ch === 95 /* _ */ ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
    }
    ts.isIdentifierStart = isIdentifierStart;
    function isIdentifierPart(ch, languageVersion) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
    }
    ts.isIdentifierPart = isIdentifierPart;
    /* @internal */
    function isIdentifierText(name, languageVersion) {
        if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) {
            return false;
        }
        for (var i = 1; i < name.length; i++) {
            if (!isIdentifierPart(name.charCodeAt(i), languageVersion)) {
                return false;
            }
        }
        return true;
    }
    ts.isIdentifierText = isIdentifierText;
    // Creates a scanner over a (possibly unspecified) range of a piece of text.
    function createScanner(languageVersion, skipTrivia, languageVariant, text, onError, start, length) {
        if (languageVariant === void 0) { languageVariant = 0 /* Standard */; }
        // Current position (end position of text of current token)
        var pos;
        // end of text
        var end;
        // Start position of whitespace before current token
        var startPos;
        // Start position of text of current token
        var tokenPos;
        var token;
        var tokenValue;
        var precedingLineBreak;
        var hasExtendedUnicodeEscape;
        var tokenIsUnterminated;
        var numericLiteralFlags;
        setText(text, start, length);
        return {
            getStartPos: function () { return startPos; },
            getTextPos: function () { return pos; },
            getToken: function () { return token; },
            getTokenPos: function () { return tokenPos; },
            getTokenText: function () { return text.substring(tokenPos, pos); },
            getTokenValue: function () { return tokenValue; },
            hasExtendedUnicodeEscape: function () { return hasExtendedUnicodeEscape; },
            hasPrecedingLineBreak: function () { return precedingLineBreak; },
            isIdentifier: function () { return token === 71 /* Identifier */ || token > 107 /* LastReservedWord */; },
            isReservedWord: function () { return token >= 72 /* FirstReservedWord */ && token <= 107 /* LastReservedWord */; },
            isUnterminated: function () { return tokenIsUnterminated; },
            getNumericLiteralFlags: function () { return numericLiteralFlags; },
            reScanGreaterToken: reScanGreaterToken,
            reScanSlashToken: reScanSlashToken,
            reScanTemplateToken: reScanTemplateToken,
            scanJsxIdentifier: scanJsxIdentifier,
            scanJsxAttributeValue: scanJsxAttributeValue,
            reScanJsxToken: reScanJsxToken,
            scanJsxToken: scanJsxToken,
            scanJSDocToken: scanJSDocToken,
            scan: scan,
            getText: getText,
            setText: setText,
            setScriptTarget: setScriptTarget,
            setLanguageVariant: setLanguageVariant,
            setOnError: setOnError,
            setTextPos: setTextPos,
            tryScan: tryScan,
            lookAhead: lookAhead,
            scanRange: scanRange,
        };
        function error(message, length) {
            if (onError) {
                onError(message, length || 0);
            }
        }
        function scanNumber() {
            var start = pos;
            while (isDigit(text.charCodeAt(pos)))
                pos++;
            if (text.charCodeAt(pos) === 46 /* dot */) {
                pos++;
                while (isDigit(text.charCodeAt(pos)))
                    pos++;
            }
            var end = pos;
            if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) {
                pos++;
                numericLiteralFlags = 2 /* Scientific */;
                if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */)
                    pos++;
                if (isDigit(text.charCodeAt(pos))) {
                    pos++;
                    while (isDigit(text.charCodeAt(pos)))
                        pos++;
                    end = pos;
                }
                else {
                    error(ts.Diagnostics.Digit_expected);
                }
            }
            return "" + +(text.substring(start, end));
        }
        function scanOctalDigits() {
            var start = pos;
            while (isOctalDigit(text.charCodeAt(pos))) {
                pos++;
            }
            return +(text.substring(start, pos));
        }
        /**
         * Scans the given number of hexadecimal digits in the text,
         * returning -1 if the given number is unavailable.
         */
        function scanExactNumberOfHexDigits(count) {
            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false);
        }
        /**
         * Scans as many hexadecimal digits as are available in the text,
         * returning -1 if the given number of digits was unavailable.
         */
        function scanMinimumNumberOfHexDigits(count) {
            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true);
        }
        function scanHexDigits(minCount, scanAsManyAsPossible) {
            var digits = 0;
            var value = 0;
            while (digits < minCount || scanAsManyAsPossible) {
                var ch = text.charCodeAt(pos);
                if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
                    value = value * 16 + ch - 48 /* _0 */;
                }
                else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
                    value = value * 16 + ch - 65 /* A */ + 10;
                }
                else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
                    value = value * 16 + ch - 97 /* a */ + 10;
                }
                else {
                    break;
                }
                pos++;
                digits++;
            }
            if (digits < minCount) {
                value = -1;
            }
            return value;
        }
        function scanString(allowEscapes) {
            if (allowEscapes === void 0) { allowEscapes = true; }
            var quote = text.charCodeAt(pos);
            pos++;
            var result = "";
            var start = pos;
            while (true) {
                if (pos >= end) {
                    result += text.substring(start, pos);
                    tokenIsUnterminated = true;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                var ch = text.charCodeAt(pos);
                if (ch === quote) {
                    result += text.substring(start, pos);
                    pos++;
                    break;
                }
                if (ch === 92 /* backslash */ && allowEscapes) {
                    result += text.substring(start, pos);
                    result += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                if (isLineBreak(ch)) {
                    result += text.substring(start, pos);
                    tokenIsUnterminated = true;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                pos++;
            }
            return result;
        }
        /**
         * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
         * a literal component of a TemplateExpression.
         */
        function scanTemplateAndSetTokenValue() {
            var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
            pos++;
            var start = pos;
            var contents = "";
            var resultingToken;
            while (true) {
                if (pos >= end) {
                    contents += text.substring(start, pos);
                    tokenIsUnterminated = true;
                    error(ts.Diagnostics.Unterminated_template_literal);
                    resultingToken = startedWithBacktick ? 13 /* NoSubstitutionTemplateLiteral */ : 16 /* TemplateTail */;
                    break;
                }
                var currChar = text.charCodeAt(pos);
                // '`'
                if (currChar === 96 /* backtick */) {
                    contents += text.substring(start, pos);
                    pos++;
                    resultingToken = startedWithBacktick ? 13 /* NoSubstitutionTemplateLiteral */ : 16 /* TemplateTail */;
                    break;
                }
                // '${'
                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                    contents += text.substring(start, pos);
                    pos += 2;
                    resultingToken = startedWithBacktick ? 14 /* TemplateHead */ : 15 /* TemplateMiddle */;
                    break;
                }
                // Escape character
                if (currChar === 92 /* backslash */) {
                    contents += text.substring(start, pos);
                    contents += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                // Speculated ECMAScript 6 Spec 11.8.6.1:
                // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
                if (currChar === 13 /* carriageReturn */) {
                    contents += text.substring(start, pos);
                    pos++;
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                    contents += "\n";
                    start = pos;
                    continue;
                }
                pos++;
            }
            ts.Debug.assert(resultingToken !== undefined);
            tokenValue = contents;
            return resultingToken;
        }
        function scanEscapeSequence() {
            pos++;
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                return "";
            }
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 48 /* _0 */:
                    return "\0";
                case 98 /* b */:
                    return "\b";
                case 116 /* t */:
                    return "\t";
                case 110 /* n */:
                    return "\n";
                case 118 /* v */:
                    return "\v";
                case 102 /* f */:
                    return "\f";
                case 114 /* r */:
                    return "\r";
                case 39 /* singleQuote */:
                    return "\'";
                case 34 /* doubleQuote */:
                    return "\"";
                case 117 /* u */:
                    // '\u{DDDDDDDD}'
                    if (pos < end && text.charCodeAt(pos) === 123 /* openBrace */) {
                        hasExtendedUnicodeEscape = true;
                        pos++;
                        return scanExtendedUnicodeEscape();
                    }
                    // '\uDDDD'
                    return scanHexadecimalEscape(/*numDigits*/ 4);
                case 120 /* x */:
                    // '\xDD'
                    return scanHexadecimalEscape(/*numDigits*/ 2);
                // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
                // the line terminator is interpreted to be "the empty code unit sequence".
                case 13 /* carriageReturn */:
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                case 8232 /* lineSeparator */:
                case 8233 /* paragraphSeparator */:
                    return "";
                default:
                    return String.fromCharCode(ch);
            }
        }
        function scanHexadecimalEscape(numDigits) {
            var escapedValue = scanExactNumberOfHexDigits(numDigits);
            if (escapedValue >= 0) {
                return String.fromCharCode(escapedValue);
            }
            else {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                return "";
            }
        }
        function scanExtendedUnicodeEscape() {
            var escapedValue = scanMinimumNumberOfHexDigits(1);
            var isInvalidExtendedEscape = false;
            // Validate the value of the digit
            if (escapedValue < 0) {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                isInvalidExtendedEscape = true;
            }
            else if (escapedValue > 0x10FFFF) {
                error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive);
                isInvalidExtendedEscape = true;
            }
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                isInvalidExtendedEscape = true;
            }
            else if (text.charCodeAt(pos) === 125 /* closeBrace */) {
                // Only swallow the following character up if it's a '}'.
                pos++;
            }
            else {
                error(ts.Diagnostics.Unterminated_Unicode_escape_sequence);
                isInvalidExtendedEscape = true;
            }
            if (isInvalidExtendedEscape) {
                return "";
            }
            return utf16EncodeAsString(escapedValue);
        }
        // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec.
        function utf16EncodeAsString(codePoint) {
            ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF);
            if (codePoint <= 65535) {
                return String.fromCharCode(codePoint);
            }
            var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800;
            var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00;
            return String.fromCharCode(codeUnit1, codeUnit2);
        }
        // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX'
        // and return code point value if valid Unicode escape is found. Otherwise return -1.
        function peekUnicodeEscape() {
            if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) {
                var start_1 = pos;
                pos += 2;
                var value = scanExactNumberOfHexDigits(4);
                pos = start_1;
                return value;
            }
            return -1;
        }
        function scanIdentifierParts() {
            var result = "";
            var start = pos;
            while (pos < end) {
                var ch = text.charCodeAt(pos);
                if (isIdentifierPart(ch, languageVersion)) {
                    pos++;
                }
                else if (ch === 92 /* backslash */) {
                    ch = peekUnicodeEscape();
                    if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) {
                        break;
                    }
                    result += text.substring(start, pos);
                    result += String.fromCharCode(ch);
                    // Valid Unicode escape is always six characters
                    pos += 6;
                    start = pos;
                }
                else {
                    break;
                }
            }
            result += text.substring(start, pos);
            return result;
        }
        function getIdentifierToken() {
            // Reserved words are between 2 and 11 characters long and start with a lowercase letter
            var len = tokenValue.length;
            if (len >= 2 && len <= 11) {
                var ch = tokenValue.charCodeAt(0);
                if (ch >= 97 /* a */ && ch <= 122 /* z */) {
                    token = textToToken.get(tokenValue);
                    if (token !== undefined) {
                        return token;
                    }
                }
            }
            return token = 71 /* Identifier */;
        }
        function scanBinaryOrOctalDigits(base) {
            ts.Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8");
            var value = 0;
            // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
            // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
            var numberOfDigits = 0;
            while (true) {
                var ch = text.charCodeAt(pos);
                var valueOfCh = ch - 48 /* _0 */;
                if (!isDigit(ch) || valueOfCh >= base) {
                    break;
                }
                value = value * base + valueOfCh;
                pos++;
                numberOfDigits++;
            }
            // Invalid binaryIntegerLiteral or octalIntegerLiteral
            if (numberOfDigits === 0) {
                return -1;
            }
            return value;
        }
        function scan() {
            startPos = pos;
            hasExtendedUnicodeEscape = false;
            precedingLineBreak = false;
            tokenIsUnterminated = false;
            numericLiteralFlags = 0;
            while (true) {
                tokenPos = pos;
                if (pos >= end) {
                    return token = 1 /* EndOfFileToken */;
                }
                var ch = text.charCodeAt(pos);
                // Special handling for shebang
                if (ch === 35 /* hash */ && pos === 0 && isShebangTrivia(text, pos)) {
                    pos = scanShebangTrivia(text, pos);
                    if (skipTrivia) {
                        continue;
                    }
                    else {
                        return token = 6 /* ShebangTrivia */;
                    }
                }
                switch (ch) {
                    case 10 /* lineFeed */:
                    case 13 /* carriageReturn */:
                        precedingLineBreak = true;
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            if (ch === 13 /* carriageReturn */ && pos + 1 < end && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                                // consume both CR and LF
                                pos += 2;
                            }
                            else {
                                pos++;
                            }
                            return token = 4 /* NewLineTrivia */;
                        }
                    case 9 /* tab */:
                    case 11 /* verticalTab */:
                    case 12 /* formFeed */:
                    case 32 /* space */:
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                                pos++;
                            }
                            return token = 5 /* WhitespaceTrivia */;
                        }
                    case 33 /* exclamation */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 35 /* ExclamationEqualsEqualsToken */;
                            }
                            return pos += 2, token = 33 /* ExclamationEqualsToken */;
                        }
                        pos++;
                        return token = 51 /* ExclamationToken */;
                    case 34 /* doubleQuote */:
                    case 39 /* singleQuote */:
                        tokenValue = scanString();
                        return token = 9 /* StringLiteral */;
                    case 96 /* backtick */:
                        return token = scanTemplateAndSetTokenValue();
                    case 37 /* percent */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 64 /* PercentEqualsToken */;
                        }
                        pos++;
                        return token = 42 /* PercentToken */;
                    case 38 /* ampersand */:
                        if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
                            return pos += 2, token = 53 /* AmpersandAmpersandToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 68 /* AmpersandEqualsToken */;
                        }
                        pos++;
                        return token = 48 /* AmpersandToken */;
                    case 40 /* openParen */:
                        pos++;
                        return token = 19 /* OpenParenToken */;
                    case 41 /* closeParen */:
                        pos++;
                        return token = 20 /* CloseParenToken */;
                    case 42 /* asterisk */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 61 /* AsteriskEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 62 /* AsteriskAsteriskEqualsToken */;
                            }
                            return pos += 2, token = 40 /* AsteriskAsteriskToken */;
                        }
                        pos++;
                        return token = 39 /* AsteriskToken */;
                    case 43 /* plus */:
                        if (text.charCodeAt(pos + 1) === 43 /* plus */) {
                            return pos += 2, token = 43 /* PlusPlusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 59 /* PlusEqualsToken */;
                        }
                        pos++;
                        return token = 37 /* PlusToken */;
                    case 44 /* comma */:
                        pos++;
                        return token = 26 /* CommaToken */;
                    case 45 /* minus */:
                        if (text.charCodeAt(pos + 1) === 45 /* minus */) {
                            return pos += 2, token = 44 /* MinusMinusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 60 /* MinusEqualsToken */;
                        }
                        pos++;
                        return token = 38 /* MinusToken */;
                    case 46 /* dot */:
                        if (isDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = scanNumber();
                            return token = 8 /* NumericLiteral */;
                        }
                        if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
                            return pos += 3, token = 24 /* DotDotDotToken */;
                        }
                        pos++;
                        return token = 23 /* DotToken */;
                    case 47 /* slash */:
                        // Single-line comment
                        if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                            pos += 2;
                            while (pos < end) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    break;
                                }
                                pos++;
                            }
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 2 /* SingleLineCommentTrivia */;
                            }
                        }
                        // Multi-line comment
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            pos += 2;
                            var commentClosed = false;
                            while (pos < end) {
                                var ch_1 = text.charCodeAt(pos);
                                if (ch_1 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    commentClosed = true;
                                    break;
                                }
                                if (isLineBreak(ch_1)) {
                                    precedingLineBreak = true;
                                }
                                pos++;
                            }
                            if (!commentClosed) {
                                error(ts.Diagnostics.Asterisk_Slash_expected);
                            }
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                tokenIsUnterminated = !commentClosed;
                                return token = 3 /* MultiLineCommentTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 63 /* SlashEqualsToken */;
                        }
                        pos++;
                        return token = 41 /* SlashToken */;
                    case 48 /* _0 */:
                        if (pos + 2 < end && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) {
                            pos += 2;
                            var value = scanMinimumNumberOfHexDigits(1);
                            if (value < 0) {
                                error(ts.Diagnostics.Hexadecimal_digit_expected);
                                value = 0;
                            }
                            tokenValue = "" + value;
                            numericLiteralFlags = 8 /* HexSpecifier */;
                            return token = 8 /* NumericLiteral */;
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 66 /* B */ || text.charCodeAt(pos + 1) === 98 /* b */)) {
                            pos += 2;
                            var value = scanBinaryOrOctalDigits(/* base */ 2);
                            if (value < 0) {
                                error(ts.Diagnostics.Binary_digit_expected);
                                value = 0;
                            }
                            tokenValue = "" + value;
                            numericLiteralFlags = 16 /* BinarySpecifier */;
                            return token = 8 /* NumericLiteral */;
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 79 /* O */ || text.charCodeAt(pos + 1) === 111 /* o */)) {
                            pos += 2;
                            var value = scanBinaryOrOctalDigits(/* base */ 8);
                            if (value < 0) {
                                error(ts.Diagnostics.Octal_digit_expected);
                                value = 0;
                            }
                            tokenValue = "" + value;
                            numericLiteralFlags = 32 /* OctalSpecifier */;
                            return token = 8 /* NumericLiteral */;
                        }
                        // Try to parse as an octal
                        if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = "" + scanOctalDigits();
                            numericLiteralFlags = 4 /* Octal */;
                            return token = 8 /* NumericLiteral */;
                        }
                    // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
                    // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
                    // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
                    // falls through
                    case 49 /* _1 */:
                    case 50 /* _2 */:
                    case 51 /* _3 */:
                    case 52 /* _4 */:
                    case 53 /* _5 */:
                    case 54 /* _6 */:
                    case 55 /* _7 */:
                    case 56 /* _8 */:
                    case 57 /* _9 */:
                        tokenValue = scanNumber();
                        return token = 8 /* NumericLiteral */;
                    case 58 /* colon */:
                        pos++;
                        return token = 56 /* ColonToken */;
                    case 59 /* semicolon */:
                        pos++;
                        return token = 25 /* SemicolonToken */;
                    case 60 /* lessThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 60 /* lessThan */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 65 /* LessThanLessThanEqualsToken */;
                            }
                            return pos += 2, token = 45 /* LessThanLessThanToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 30 /* LessThanEqualsToken */;
                        }
                        if (languageVariant === 1 /* JSX */ &&
                            text.charCodeAt(pos + 1) === 47 /* slash */ &&
                            text.charCodeAt(pos + 2) !== 42 /* asterisk */) {
                            return pos += 2, token = 28 /* LessThanSlashToken */;
                        }
                        pos++;
                        return token = 27 /* LessThanToken */;
                    case 61 /* equals */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 34 /* EqualsEqualsEqualsToken */;
                            }
                            return pos += 2, token = 32 /* EqualsEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                            return pos += 2, token = 36 /* EqualsGreaterThanToken */;
                        }
                        pos++;
                        return token = 58 /* EqualsToken */;
                    case 62 /* greaterThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        pos++;
                        return token = 29 /* GreaterThanToken */;
                    case 63 /* question */:
                        pos++;
                        return token = 55 /* QuestionToken */;
                    case 91 /* openBracket */:
                        pos++;
                        return token = 21 /* OpenBracketToken */;
                    case 93 /* closeBracket */:
                        pos++;
                        return token = 22 /* CloseBracketToken */;
                    case 94 /* caret */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 70 /* CaretEqualsToken */;
                        }
                        pos++;
                        return token = 50 /* CaretToken */;
                    case 123 /* openBrace */:
                        pos++;
                        return token = 17 /* OpenBraceToken */;
                    case 124 /* bar */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 124 /* bar */) {
                            return pos += 2, token = 54 /* BarBarToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 69 /* BarEqualsToken */;
                        }
                        pos++;
                        return token = 49 /* BarToken */;
                    case 125 /* closeBrace */:
                        pos++;
                        return token = 18 /* CloseBraceToken */;
                    case 126 /* tilde */:
                        pos++;
                        return token = 52 /* TildeToken */;
                    case 64 /* at */:
                        pos++;
                        return token = 57 /* AtToken */;
                    case 92 /* backslash */:
                        var cookedChar = peekUnicodeEscape();
                        if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
                            pos += 6;
                            tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
                            return token = getIdentifierToken();
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos++;
                        return token = 0 /* Unknown */;
                    default:
                        if (isIdentifierStart(ch, languageVersion)) {
                            pos++;
                            while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion))
                                pos++;
                            tokenValue = text.substring(tokenPos, pos);
                            if (ch === 92 /* backslash */) {
                                tokenValue += scanIdentifierParts();
                            }
                            return token = getIdentifierToken();
                        }
                        else if (isWhiteSpaceSingleLine(ch)) {
                            pos++;
                            continue;
                        }
                        else if (isLineBreak(ch)) {
                            precedingLineBreak = true;
                            pos++;
                            continue;
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos++;
                        return token = 0 /* Unknown */;
                }
            }
        }
        function reScanGreaterToken() {
            if (token === 29 /* GreaterThanToken */) {
                if (text.charCodeAt(pos) === 62 /* greaterThan */) {
                    if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                        if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                            return pos += 3, token = 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
                        }
                        return pos += 2, token = 47 /* GreaterThanGreaterThanGreaterThanToken */;
                    }
                    if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                        return pos += 2, token = 66 /* GreaterThanGreaterThanEqualsToken */;
                    }
                    pos++;
                    return token = 46 /* GreaterThanGreaterThanToken */;
                }
                if (text.charCodeAt(pos) === 61 /* equals */) {
                    pos++;
                    return token = 31 /* GreaterThanEqualsToken */;
                }
            }
            return token;
        }
        function reScanSlashToken() {
            if (token === 41 /* SlashToken */ || token === 63 /* SlashEqualsToken */) {
                var p = tokenPos + 1;
                var inEscape = false;
                var inCharacterClass = false;
                while (true) {
                    // If we reach the end of a file, or hit a newline, then this is an unterminated
                    // regex.  Report error and return what we have so far.
                    if (p >= end) {
                        tokenIsUnterminated = true;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    var ch = text.charCodeAt(p);
                    if (isLineBreak(ch)) {
                        tokenIsUnterminated = true;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    if (inEscape) {
                        // Parsing an escape character;
                        // reset the flag and just advance to the next char.
                        inEscape = false;
                    }
                    else if (ch === 47 /* slash */ && !inCharacterClass) {
                        // A slash within a character class is permissible,
                        // but in general it signals the end of the regexp literal.
                        p++;
                        break;
                    }
                    else if (ch === 91 /* openBracket */) {
                        inCharacterClass = true;
                    }
                    else if (ch === 92 /* backslash */) {
                        inEscape = true;
                    }
                    else if (ch === 93 /* closeBracket */) {
                        inCharacterClass = false;
                    }
                    p++;
                }
                while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) {
                    p++;
                }
                pos = p;
                tokenValue = text.substring(tokenPos, pos);
                token = 12 /* RegularExpressionLiteral */;
            }
            return token;
        }
        /**
         * Unconditionally back up and scan a template expression portion.
         */
        function reScanTemplateToken() {
            ts.Debug.assert(token === 18 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'");
            pos = tokenPos;
            return token = scanTemplateAndSetTokenValue();
        }
        function reScanJsxToken() {
            pos = tokenPos = startPos;
            return token = scanJsxToken();
        }
        function scanJsxToken() {
            startPos = tokenPos = pos;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var char = text.charCodeAt(pos);
            if (char === 60 /* lessThan */) {
                if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                    pos += 2;
                    return token = 28 /* LessThanSlashToken */;
                }
                pos++;
                return token = 27 /* LessThanToken */;
            }
            if (char === 123 /* openBrace */) {
                pos++;
                return token = 17 /* OpenBraceToken */;
            }
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitspace,
            while (pos < end) {
                char = text.charCodeAt(pos);
                if (char === 123 /* openBrace */) {
                    break;
                }
                if (char === 60 /* lessThan */) {
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos, error);
                        return token = 7 /* ConflictMarkerTrivia */;
                    }
                    break;
                }
                // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces.
                // i.e (- : whitespace)
                //      <div>----
                //      </div> becomes <div></div>
                //
                //      <div>----</div> becomes <div>----</div>
                if (isLineBreak(char) && firstNonWhitespace === 0) {
                    firstNonWhitespace = -1;
                }
                else if (!isWhiteSpaceLike(char)) {
                    firstNonWhitespace = pos;
                }
                pos++;
            }
            return firstNonWhitespace === -1 ? 11 /* JsxTextAllWhiteSpaces */ : 10 /* JsxText */;
        }
        // Scans a JSX identifier; these differ from normal identifiers in that
        // they allow dashes
        function scanJsxIdentifier() {
            if (tokenIsIdentifierOrKeyword(token)) {
                var firstCharPosition = pos;
                while (pos < end) {
                    var ch = text.charCodeAt(pos);
                    if (ch === 45 /* minus */ || ((firstCharPosition === pos) ? isIdentifierStart(ch, languageVersion) : isIdentifierPart(ch, languageVersion))) {
                        pos++;
                    }
                    else {
                        break;
                    }
                }
                tokenValue += text.substr(firstCharPosition, pos - firstCharPosition);
            }
            return token;
        }
        function scanJsxAttributeValue() {
            startPos = pos;
            switch (text.charCodeAt(pos)) {
                case 34 /* doubleQuote */:
                case 39 /* singleQuote */:
                    tokenValue = scanString(/*allowEscapes*/ false);
                    return token = 9 /* StringLiteral */;
                default:
                    // If this scans anything other than `{`, it's a parse error.
                    return scan();
            }
        }
        function scanJSDocToken() {
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            startPos = pos;
            tokenPos = pos;
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                        pos++;
                    }
                    return token = 5 /* WhitespaceTrivia */;
                case 64 /* at */:
                    pos++;
                    return token = 57 /* AtToken */;
                case 10 /* lineFeed */:
                case 13 /* carriageReturn */:
                    pos++;
                    return token = 4 /* NewLineTrivia */;
                case 42 /* asterisk */:
                    pos++;
                    return token = 39 /* AsteriskToken */;
                case 123 /* openBrace */:
                    pos++;
                    return token = 17 /* OpenBraceToken */;
                case 125 /* closeBrace */:
                    pos++;
                    return token = 18 /* CloseBraceToken */;
                case 91 /* openBracket */:
                    pos++;
                    return token = 21 /* OpenBracketToken */;
                case 93 /* closeBracket */:
                    pos++;
                    return token = 22 /* CloseBracketToken */;
                case 60 /* lessThan */:
                    pos++;
                    return token = 27 /* LessThanToken */;
                case 62 /* greaterThan */:
                    pos++;
                    return token = 29 /* GreaterThanToken */;
                case 61 /* equals */:
                    pos++;
                    return token = 58 /* EqualsToken */;
                case 44 /* comma */:
                    pos++;
                    return token = 26 /* CommaToken */;
                case 46 /* dot */:
                    pos++;
                    return token = 23 /* DotToken */;
            }
            if (isIdentifierStart(ch, 5 /* Latest */)) {
                pos++;
                while (isIdentifierPart(text.charCodeAt(pos), 5 /* Latest */) && pos < end) {
                    pos++;
                }
                return token = 71 /* Identifier */;
            }
            else {
                return pos += 1, token = 0 /* Unknown */;
            }
        }
        function speculationHelper(callback, isLookahead) {
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var savePrecedingLineBreak = precedingLineBreak;
            var result = callback();
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookahead) {
                pos = savePos;
                startPos = saveStartPos;
                tokenPos = saveTokenPos;
                token = saveToken;
                tokenValue = saveTokenValue;
                precedingLineBreak = savePrecedingLineBreak;
            }
            return result;
        }
        function scanRange(start, length, callback) {
            var saveEnd = end;
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var savePrecedingLineBreak = precedingLineBreak;
            var saveTokenValue = tokenValue;
            var saveHasExtendedUnicodeEscape = hasExtendedUnicodeEscape;
            var saveTokenIsUnterminated = tokenIsUnterminated;
            setText(text, start, length);
            var result = callback();
            end = saveEnd;
            pos = savePos;
            startPos = saveStartPos;
            tokenPos = saveTokenPos;
            token = saveToken;
            precedingLineBreak = savePrecedingLineBreak;
            tokenValue = saveTokenValue;
            hasExtendedUnicodeEscape = saveHasExtendedUnicodeEscape;
            tokenIsUnterminated = saveTokenIsUnterminated;
            return result;
        }
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookahead*/ true);
        }
        function tryScan(callback) {
            return speculationHelper(callback, /*isLookahead*/ false);
        }
        function getText() {
            return text;
        }
        function setText(newText, start, length) {
            text = newText || "";
            end = length === undefined ? text.length : start + length;
            setTextPos(start || 0);
        }
        function setOnError(errorCallback) {
            onError = errorCallback;
        }
        function setScriptTarget(scriptTarget) {
            languageVersion = scriptTarget;
        }
        function setLanguageVariant(variant) {
            languageVariant = variant;
        }
        function setTextPos(textPos) {
            ts.Debug.assert(textPos >= 0);
            pos = textPos;
            startPos = textPos;
            tokenPos = textPos;
            token = 0 /* Unknown */;
            precedingLineBreak = false;
            tokenValue = undefined;
            hasExtendedUnicodeEscape = false;
            tokenIsUnterminated = false;
        }
    }
    ts.createScanner = createScanner;
})(ts || (ts = {}));
/// <reference path="sys.ts" />
/* @internal */
var ts;
(function (ts) {
    ts.emptyArray = [];
    ts.emptyMap = ts.createMap();
    ts.externalHelpersModuleNameText = "tslib";
    function getDeclarationOfKind(symbol, kind) {
        var declarations = symbol.declarations;
        if (declarations) {
            for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                var declaration = declarations_1[_i];
                if (declaration.kind === kind) {
                    return declaration;
                }
            }
        }
        return undefined;
    }
    ts.getDeclarationOfKind = getDeclarationOfKind;
    var stringWriter = createSingleLineStringWriter();
    function createSingleLineStringWriter() {
        var str = "";
        var writeText = function (text) { return str += text; };
        return {
            string: function () { return str; },
            writeKeyword: writeText,
            writeOperator: writeText,
            writePunctuation: writeText,
            writeSpace: writeText,
            writeStringLiteral: writeText,
            writeParameter: writeText,
            writeProperty: writeText,
            writeSymbol: writeText,
            // Completely ignore indentation for string writers.  And map newlines to
            // a single space.
            writeLine: function () { return str += " "; },
            increaseIndent: ts.noop,
            decreaseIndent: ts.noop,
            clear: function () { return str = ""; },
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
    }
    function usingSingleLineStringWriter(action) {
        var oldString = stringWriter.string();
        try {
            action(stringWriter);
            return stringWriter.string();
        }
        finally {
            stringWriter.clear();
            stringWriter.writeKeyword(oldString);
        }
    }
    ts.usingSingleLineStringWriter = usingSingleLineStringWriter;
    function getFullWidth(node) {
        return node.end - node.pos;
    }
    ts.getFullWidth = getFullWidth;
    function getResolvedModule(sourceFile, moduleNameText) {
        return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
    }
    ts.getResolvedModule = getResolvedModule;
    function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
        if (!sourceFile.resolvedModules) {
            sourceFile.resolvedModules = ts.createMap();
        }
        sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
    }
    ts.setResolvedModule = setResolvedModule;
    function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) {
        if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
            sourceFile.resolvedTypeReferenceDirectiveNames = ts.createMap();
        }
        sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
    }
    ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective;
    function moduleResolutionIsEqualTo(oldResolution, newResolution) {
        return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
            oldResolution.extension === newResolution.extension &&
            oldResolution.resolvedFileName === newResolution.resolvedFileName &&
            packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
    }
    ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo;
    function packageIdIsEqual(a, b) {
        return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
    }
    function typeDirectiveIsEqualTo(oldResolution, newResolution) {
        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary;
    }
    ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo;
    function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) {
        ts.Debug.assert(names.length === newResolutions.length);
        for (var i = 0; i < names.length; i++) {
            var newResolution = newResolutions[i];
            var oldResolution = oldResolutions && oldResolutions.get(names[i]);
            var changed = oldResolution
                ? !newResolution || !comparer(oldResolution, newResolution)
                : newResolution;
            if (changed) {
                return true;
            }
        }
        return false;
    }
    ts.hasChangesInResolutions = hasChangesInResolutions;
    // Returns true if this node contains a parse error anywhere underneath it.
    function containsParseError(node) {
        aggregateChildData(node);
        return (node.flags & 131072 /* ThisNodeOrAnySubNodesHasError */) !== 0;
    }
    ts.containsParseError = containsParseError;
    function aggregateChildData(node) {
        if (!(node.flags & 262144 /* HasAggregatedChildData */)) {
            // A node is considered to contain a parse error if:
            //  a) the parser explicitly marked that it had an error
            //  b) any of it's children reported that it had an error.
            var thisNodeOrAnySubNodesHasError = ((node.flags & 32768 /* ThisNodeHasError */) !== 0) ||
                ts.forEachChild(node, containsParseError);
            // If so, mark ourselves accordingly.
            if (thisNodeOrAnySubNodesHasError) {
                node.flags |= 131072 /* ThisNodeOrAnySubNodesHasError */;
            }
            // Also mark that we've propagated the child information to this node.  This way we can
            // always consult the bit directly on this node without needing to check its children
            // again.
            node.flags |= 262144 /* HasAggregatedChildData */;
        }
    }
    function getSourceFileOfNode(node) {
        while (node && node.kind !== 265 /* SourceFile */) {
            node = node.parent;
        }
        return node;
    }
    ts.getSourceFileOfNode = getSourceFileOfNode;
    function isStatementWithLocals(node) {
        switch (node.kind) {
            case 207 /* Block */:
            case 235 /* CaseBlock */:
            case 214 /* ForStatement */:
            case 215 /* ForInStatement */:
            case 216 /* ForOfStatement */:
                return true;
        }
        return false;
    }
    ts.isStatementWithLocals = isStatementWithLocals;
    function getStartPositionOfLine(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        return ts.getLineStarts(sourceFile)[line];
    }
    ts.getStartPositionOfLine = getStartPositionOfLine;
    // This is a useful function for debugging purposes.
    function nodePosToString(node) {
        var file = getSourceFileOfNode(node);
        var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
        return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
    }
    ts.nodePosToString = nodePosToString;
    function getEndLinePosition(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        var lineStarts = ts.getLineStarts(sourceFile);
        var lineIndex = line;
        var sourceText = sourceFile.text;
        if (lineIndex + 1 === lineStarts.length) {
            // last line - return EOF
            return sourceText.length - 1;
        }
        else {
            // current line start
            var start = lineStarts[lineIndex];
            // take the start position of the next line - 1 = it should be some line break
            var pos = lineStarts[lineIndex + 1] - 1;
            ts.Debug.assert(ts.isLineBreak(sourceText.charCodeAt(pos)));
            // walk backwards skipping line breaks, stop the the beginning of current line.
            // i.e:
            // <some text>
            // $ <- end of line for this position should match the start position
            while (start <= pos && ts.isLineBreak(sourceText.charCodeAt(pos))) {
                pos--;
            }
            return pos;
        }
    }
    ts.getEndLinePosition = getEndLinePosition;
    // Returns true if this node is missing from the actual source code. A 'missing' node is different
    // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
    // in the tree), it is definitely missing. However, a node may be defined, but still be
    // missing.  This happens whenever the parser knows it needs to parse something, but can't
    // get anything in the source code that it expects at that location. For example:
    //
    //          let a: ;
    //
    // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
    // code). So the parser will attempt to parse out a type, and will create an actual node.
    // However, this node will be 'missing' in the sense that no actual source-code/tokens are
    // contained within it.
    function nodeIsMissing(node) {
        if (node === undefined) {
            return true;
        }
        return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
    }
    ts.nodeIsMissing = nodeIsMissing;
    function nodeIsPresent(node) {
        return !nodeIsMissing(node);
    }
    ts.nodeIsPresent = nodeIsPresent;
    /**
     * Determine if the given comment is a triple-slash
     *
     * @return true if the comment is a triple-slash comment else false
     */
    function isRecognizedTripleSlashComment(text, commentPos, commentEnd) {
        // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
        // so that we don't end up computing comment string and doing match for all // comments
        if (text.charCodeAt(commentPos + 1) === 47 /* slash */ &&
            commentPos + 2 < commentEnd &&
            text.charCodeAt(commentPos + 2) === 47 /* slash */) {
            var textSubStr = text.substring(commentPos, commentEnd);
            return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
                textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ||
                textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) ||
                textSubStr.match(defaultLibReferenceRegEx) ?
                true : false;
        }
        return false;
    }
    ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment;
    function isPinnedComment(text, comment) {
        return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
            text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
    }
    ts.isPinnedComment = isPinnedComment;
    function getTokenPosOfNode(node, sourceFile, includeJsDoc) {
        // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
        // want to skip trivia because this will launch us forward to the next token.
        if (nodeIsMissing(node)) {
            return node.pos;
        }
        if (ts.isJSDocNode(node)) {
            return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        if (includeJsDoc && ts.hasJSDocNodes(node)) {
            return getTokenPosOfNode(node.jsDoc[0]);
        }
        // For a syntax list, it is possible that one of its children has JSDocComment nodes, while
        // the syntax list itself considers them as normal trivia. Therefore if we simply skip
        // trivia for the list, we may have skipped the JSDocComment as well. So we should process its
        // first child to determine the actual position of its first token.
        if (node.kind === 286 /* SyntaxList */ && node._children.length > 0) {
            return getTokenPosOfNode(node._children[0], sourceFile, includeJsDoc);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
    }
    ts.getTokenPosOfNode = getTokenPosOfNode;
    function getNonDecoratorTokenPosOfNode(node, sourceFile) {
        if (nodeIsMissing(node) || !node.decorators) {
            return getTokenPosOfNode(node, sourceFile);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
    }
    ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
    function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        if (nodeIsMissing(node)) {
            return "";
        }
        var text = sourceFile.text;
        return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
    }
    ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
    function getTextOfNodeFromSourceText(sourceText, node) {
        if (nodeIsMissing(node)) {
            return "";
        }
        return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
    }
    ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
    function getTextOfNode(node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
    }
    ts.getTextOfNode = getTextOfNode;
    /**
     * Note: it is expected that the `nodeArray` and the `node` are within the same file.
     * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work.
     */
    function indexOfNode(nodeArray, node) {
        return ts.binarySearch(nodeArray, node, compareNodePos);
    }
    ts.indexOfNode = indexOfNode;
    function compareNodePos(_a, _b) {
        var aPos = _a.pos;
        var bPos = _b.pos;
        return aPos < bPos ? -1 /* LessThan */ : bPos < aPos ? 1 /* GreaterThan */ : 0 /* EqualTo */;
    }
    /**
     * Gets flags that control emit behavior of a node.
     */
    function getEmitFlags(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.flags;
    }
    ts.getEmitFlags = getEmitFlags;
    function getLiteralText(node, sourceFile) {
        // 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 (!nodeIsSynthesized(node) && node.parent) {
            return getSourceTextOfNodeFromSourceFile(sourceFile, node);
        }
        var escapeText = getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ? escapeString : escapeNonAsciiString;
        // If we can't reach the original source text, use the canonical form if it's a number,
        // or a (possibly escaped) quoted form of the original text if it's string-like.
        switch (node.kind) {
            case 9 /* StringLiteral */:
                if (node.singleQuote) {
                    return "'" + escapeText(node.text, 39 /* singleQuote */) + "'";
                }
                else {
                    return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"';
                }
            case 13 /* NoSubstitutionTemplateLiteral */:
                return "`" + escapeText(node.text, 96 /* backtick */) + "`";
            case 14 /* TemplateHead */:
                return "`" + escapeText(node.text, 96 /* backtick */) + "${";
            case 15 /* TemplateMiddle */:
                return "}" + escapeText(node.text, 96 /* backtick */) + "${";
            case 16 /* TemplateTail */:
                return "}" + escapeText(node.text, 96 /* backtick */) + "`";
            case 8 /* NumericLiteral */:
            case 12 /* RegularExpressionLiteral */:
                return node.text;
        }
        ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
    }
    ts.getLiteralText = getLiteralText;
    function getTextOfConstantValue(value) {
        return ts.isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
    }
    ts.getTextOfConstantValue = getTextOfConstantValue;
    // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
    function escapeLeadingUnderscores(identifier) {
        return (identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier);
    }
    ts.escapeLeadingUnderscores = escapeLeadingUnderscores;
    /**
     * @deprecated Use `id.escapedText` to get the escaped text of an Identifier.
     * @param identifier The identifier to escape
     */
    function escapeIdentifier(identifier) {
        return identifier;
    }
    ts.escapeIdentifier = escapeIdentifier;
    // Make an identifier from an external module name by extracting the string after the last "/" and replacing
    // all non-alphanumeric characters with underscores
    function makeIdentifierFromModuleName(moduleName) {
        return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
    }
    ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
    function isBlockOrCatchScoped(declaration) {
        return (ts.getCombinedNodeFlags(declaration) & 3 /* BlockScoped */) !== 0 ||
            isCatchClauseVariableDeclarationOrBindingElement(declaration);
    }
    ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
    function isCatchClauseVariableDeclarationOrBindingElement(declaration) {
        var node = getRootDeclaration(declaration);
        return node.kind === 226 /* VariableDeclaration */ && node.parent.kind === 260 /* CatchClause */;
    }
    ts.isCatchClauseVariableDeclarationOrBindingElement = isCatchClauseVariableDeclarationOrBindingElement;
    function isAmbientModule(node) {
        return node && node.kind === 233 /* ModuleDeclaration */ &&
            (node.name.kind === 9 /* StringLiteral */ || isGlobalScopeAugmentation(node));
    }
    ts.isAmbientModule = isAmbientModule;
    function isModuleWithStringLiteralName(node) {
        return ts.isModuleDeclaration(node) && node.name.kind === 9 /* StringLiteral */;
    }
    ts.isModuleWithStringLiteralName = isModuleWithStringLiteralName;
    function isNonGlobalAmbientModule(node) {
        return ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name);
    }
    ts.isNonGlobalAmbientModule = isNonGlobalAmbientModule;
    /** Given a symbol for a module, checks that it is a shorthand ambient module. */
    function isShorthandAmbientModuleSymbol(moduleSymbol) {
        return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
    }
    ts.isShorthandAmbientModuleSymbol = isShorthandAmbientModuleSymbol;
    function isShorthandAmbientModule(node) {
        // The only kind of module that can be missing a body is a shorthand ambient module.
        return node && node.kind === 233 /* ModuleDeclaration */ && (!node.body);
    }
    function isBlockScopedContainerTopLevel(node) {
        return node.kind === 265 /* SourceFile */ ||
            node.kind === 233 /* ModuleDeclaration */ ||
            ts.isFunctionLike(node);
    }
    ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel;
    function isGlobalScopeAugmentation(module) {
        return !!(module.flags & 512 /* GlobalAugmentation */);
    }
    ts.isGlobalScopeAugmentation = isGlobalScopeAugmentation;
    function isExternalModuleAugmentation(node) {
        // external module augmentation is a ambient module declaration that is either:
        // - defined in the top level scope and source file is an external module
        // - defined inside ambient module declaration located in the top level scope and source file not an external module
        if (!node || !isAmbientModule(node)) {
            return false;
        }
        switch (node.parent.kind) {
            case 265 /* SourceFile */:
                return ts.isExternalModule(node.parent);
            case 234 /* ModuleBlock */:
                return isAmbientModule(node.parent.parent) && !ts.isExternalModule(node.parent.parent.parent);
        }
        return false;
    }
    ts.isExternalModuleAugmentation = isExternalModuleAugmentation;
    function isEffectiveExternalModule(node, compilerOptions) {
        return ts.isExternalModule(node) || compilerOptions.isolatedModules;
    }
    ts.isEffectiveExternalModule = isEffectiveExternalModule;
    /* @internal */
    function isBlockScope(node, parentNode) {
        switch (node.kind) {
            case 265 /* SourceFile */:
            case 235 /* CaseBlock */:
            case 260 /* CatchClause */:
            case 233 /* ModuleDeclaration */:
            case 214 /* ForStatement */:
            case 215 /* ForInStatement */:
            case 216 /* ForOfStatement */:
            case 152 /* Constructor */:
            case 151 /* MethodDeclaration */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
            case 187 /* ArrowFunction */:
                return true;
            case 207 /* Block */:
                // function block is not considered block-scope container
                // see comment in binder.ts: bind(...), case for SyntaxKind.Block
                return parentNode && !ts.isFunctionLike(parentNode);
        }
        return false;
    }
    ts.isBlockScope = isBlockScope;
    function isDeclarationWithTypeParameters(node) {
        switch (node.kind) {
            case 155 /* CallSignature */:
            case 156 /* ConstructSignature */:
            case 150 /* MethodSignature */:
            case 157 /* IndexSignature */:
            case 160 /* FunctionType */:
            case 161 /* ConstructorType */:
            case 273 /* JSDocFunctionType */:
            case 229 /* ClassDeclaration */:
            case 199 /* ClassExpression */:
            case 230 /* InterfaceDeclaration */:
            case 231 /* TypeAliasDeclaration */:
            case 282 /* JSDocTemplateTag */:
            case 228 /* FunctionDeclaration */:
            case 151 /* MethodDeclaration */:
            case 152 /* Constructor */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 186 /* FunctionExpression */:
            case 187 /* ArrowFunction */:
                return true;
            default:
                ts.assertTypeIsNever(node);
                return false;
        }
    }
    ts.isDeclarationWithTypeParameters = isDeclarationWithTypeParameters;
    /* @internal */
    function isAnyImportSyntax(node) {
        switch (node.kind) {
            case 238 /* ImportDeclaration */:
            case 237 /* ImportEqualsDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isAnyImportSyntax = isAnyImportSyntax;
    // Gets the nearest enclosing block scope container that has the provided node
    // as a descendant, that is not the provided node.
    function getEnclosingBlockScopeContainer(node) {
        var current = node.parent;
        while (current) {
            if (isBlockScope(current, current.parent)) {
                return current;
            }
            current = current.parent;
        }
    }
    ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
    // Return display name of an identifier
    // Computed property names will just be emitted as "[<expr>]", where <expr> is the source
    // text of the expression in the computed property.
    function declarationNameToString(name) {
        return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
    }
    ts.declarationNameToString = declarationNameToString;
    function getNameFromIndexInfo(info) {
        return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
    }
    ts.getNameFromIndexInfo = getNameFromIndexInfo;
    function getTextOfPropertyName(name) {
        switch (name.kind) {
            case 71 /* Identifier */:
                return name.escapedText;
            case 9 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                return escapeLeadingUnderscores(name.text);
            case 144 /* ComputedPropertyName */:
                if (isStringOrNumericLiteral(name.expression)) {
                    return escapeLeadingUnderscores(name.expression.text);
                }
        }
        return undefined;
    }
    ts.getTextOfPropertyName = getTextOfPropertyName;
    function entityNameToString(name) {
        switch (name.kind) {
            case 71 /* Identifier */:
                return getFullWidth(name) === 0 ? ts.idText(name) : getTextOfNode(name);
            case 143 /* QualifiedName */:
                return entityNameToString(name.left) + "." + entityNameToString(name.right);
            case 179 /* PropertyAccessExpression */:
                return entityNameToString(name.expression) + "." + entityNameToString(name.name);
        }
    }
    ts.entityNameToString = entityNameToString;
    function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
        var sourceFile = getSourceFileOfNode(node);
        return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
    }
    ts.createDiagnosticForNode = createDiagnosticForNode;
    function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2) {
        var span = getErrorSpanForNode(sourceFile, node);
        return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
    }
    ts.createDiagnosticForNodeInSourceFile = createDiagnosticForNodeInSourceFile;
    function createDiagnosticForNodeFromMessageChain(node, messageChain) {
        var sourceFile = getSourceFileOfNode(node);
        var span = getErrorSpanForNode(sourceFile, node);
        return {
            file: sourceFile,
            start: span.start,
            length: span.length,
            code: messageChain.code,
            category: messageChain.category,
            messageText: messageChain.next ? messageChain : messageChain.messageText
        };
    }
    ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
    function getSpanOfTokenAtPosition(sourceFile, pos) {
        var scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
        scanner.scan();
        var start = scanner.getTokenPos();
        return ts.createTextSpanFromBounds(start, scanner.getTextPos());
    }
    ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
    function getErrorSpanForArrowFunction(sourceFile, node) {
        var pos = ts.skipTrivia(sourceFile.text, node.pos);
        if (node.body && node.body.kind === 207 /* Block */) {
            var startLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.end).line;
            if (startLine < endLine) {
                // The arrow function spans multiple lines,
                // make the error span be the first line, inclusive.
                return ts.createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
            }
        }
        return ts.createTextSpanFromBounds(pos, node.end);
    }
    function getErrorSpanForNode(sourceFile, node) {
        var errorNode = node;
        switch (node.kind) {
            case 265 /* SourceFile */:
                var pos_1 = ts.skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
                if (pos_1 === sourceFile.text.length) {
                    // file is empty - return span for the beginning of the file
                    return ts.createTextSpan(0, 0);
                }
                return getSpanOfTokenAtPosition(sourceFile, pos_1);
            // This list is a work in progress. Add missing node kinds to improve their error
            // spans.
            case 226 /* VariableDeclaration */:
            case 176 /* BindingElement */:
            case 229 /* ClassDeclaration */:
            case 199 /* ClassExpression */:
            case 230 /* InterfaceDeclaration */:
            case 233 /* ModuleDeclaration */:
            case 232 /* EnumDeclaration */:
            case 264 /* EnumMember */:
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
            case 151 /* MethodDeclaration */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 231 /* TypeAliasDeclaration */:
                errorNode = node.name;
                break;
            case 187 /* ArrowFunction */:
                return getErrorSpanForArrowFunction(sourceFile, node);
        }
        if (errorNode === undefined) {
            // If we don't have a better node, then just set the error on the first token of
            // construct.
            return getSpanOfTokenAtPosition(sourceFile, node.pos);
        }
        var pos = nodeIsMissing(errorNode)
            ? errorNode.pos
            : ts.skipTrivia(sourceFile.text, errorNode.pos);
        return ts.createTextSpanFromBounds(pos, errorNode.end);
    }
    ts.getErrorSpanForNode = getErrorSpanForNode;
    function isExternalOrCommonJsModule(file) {
        return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
    }
    ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
    function isConstEnumDeclaration(node) {
        return node.kind === 232 /* EnumDeclaration */ && isConst(node);
    }
    ts.isConstEnumDeclaration = isConstEnumDeclaration;
    function isConst(node) {
        return !!(ts.getCombinedNodeFlags(node) & 2 /* Const */)
            || !!(ts.getCombinedModifierFlags(node) & 2048 /* Const */);
    }
    ts.isConst = isConst;
    function isLet(node) {
        return !!(ts.getCombinedNodeFlags(node) & 1 /* Let */);
    }
    ts.isLet = isLet;
    function isSuperCall(n) {
        return n.kind === 181 /* CallExpression */ && n.expression.kind === 97 /* SuperKeyword */;
    }
    ts.isSuperCall = isSuperCall;
    function isImportCall(n) {
        return n.kind === 181 /* CallExpression */ && n.expression.kind === 91 /* ImportKeyword */;
    }
    ts.isImportCall = isImportCall;
    function isPrologueDirective(node) {
        return node.kind === 210 /* ExpressionStatement */
            && node.expression.kind === 9 /* StringLiteral */;
    }
    ts.isPrologueDirective = isPrologueDirective;
    function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
        return node.kind !== 10 /* JsxText */ ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
    }
    ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
    function getJSDocCommentRanges(node, text) {
        var commentRanges = (node.kind === 146 /* Parameter */ ||
            node.kind === 145 /* TypeParameter */ ||
            node.kind === 186 /* FunctionExpression */ ||
            node.kind === 187 /* ArrowFunction */ ||
            node.kind === 185 /* ParenthesizedExpression */) ?
            ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
            ts.getLeadingCommentRanges(text, node.pos);
        // True if the comment starts with '/**' but not if it is '/**/'
        return ts.filter(commentRanges, function (comment) {
            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
        });
    }
    ts.getJSDocCommentRanges = getJSDocCommentRanges;
    ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)('|")(.+?)\2.*?\/>/;
    ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/;
    function isPartOfTypeNode(node) {
        if (158 /* FirstTypeNode */ <= node.kind && node.kind <= 173 /* LastTypeNode */) {
            return true;
        }
        switch (node.kind) {
            case 119 /* AnyKeyword */:
            case 133 /* NumberKeyword */:
            case 136 /* StringKeyword */:
            case 122 /* BooleanKeyword */:
            case 137 /* SymbolKeyword */:
            case 139 /* UndefinedKeyword */:
            case 130 /* NeverKeyword */:
                return true;
            case 105 /* VoidKeyword */:
                return node.parent.kind !== 190 /* VoidExpression */;
            case 201 /* ExpressionWithTypeArguments */:
                return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
            // Identifiers and qualified names may be type nodes, depending on their context. Climb
            // above them to find the lowest container
            case 71 /* Identifier */:
                // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
                if (node.parent.kind === 143 /* QualifiedName */ && node.parent.right === node) {
                    node = node.parent;
                }
                else if (node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node) {
                    node = node.parent;
                }
                // At this point, node is either a qualified name or an identifier
                ts.Debug.assert(node.kind === 71 /* Identifier */ || node.kind === 143 /* QualifiedName */ || node.kind === 179 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'.");
            // falls through
            case 143 /* QualifiedName */:
            case 179 /* PropertyAccessExpression */:
            case 99 /* ThisKeyword */:
                var parent = node.parent;
                if (parent.kind === 162 /* TypeQuery */) {
                    return false;
                }
                // Do not recursively call isPartOfTypeNode on the parent. In the example:
                //
                //     let a: A.B.C;
                //
                // Calling isPartOfTypeNode would consider the qualified name A.B a type node.
                // Only C and A.B.C are type nodes.
                if (158 /* FirstTypeNode */ <= parent.kind && parent.kind <= 173 /* LastTypeNode */) {
                    return true;
                }
                switch (parent.kind) {
                    case 201 /* ExpressionWithTypeArguments */:
                        return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
                    case 145 /* TypeParameter */:
                        return node === parent.constraint;
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                    case 146 /* Parameter */:
                    case 226 /* VariableDeclaration */:
                        return node === parent.type;
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                    case 187 /* ArrowFunction */:
                    case 152 /* Constructor */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        return node === parent.type;
                    case 155 /* CallSignature */:
                    case 156 /* ConstructSignature */:
                    case 157 /* IndexSignature */:
                        return node === parent.type;
                    case 184 /* TypeAssertionExpression */:
                        return node === parent.type;
                    case 181 /* CallExpression */:
                    case 182 /* NewExpression */:
                        return parent.typeArguments && ts.indexOf(parent.typeArguments, node) >= 0;
                    case 183 /* TaggedTemplateExpression */:
                        // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
                        return false;
                }
        }
        return false;
    }
    ts.isPartOfTypeNode = isPartOfTypeNode;
    function isChildOfNodeWithKind(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    ts.isChildOfNodeWithKind = isChildOfNodeWithKind;
    // Warning: This has the same semantics as the forEach family of functions,
    //          in that traversal terminates in the event that 'visitor' supplies a truthy value.
    function forEachReturnStatement(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 219 /* ReturnStatement */:
                    return visitor(node);
                case 235 /* CaseBlock */:
                case 207 /* Block */:
                case 211 /* IfStatement */:
                case 212 /* DoStatement */:
                case 213 /* WhileStatement */:
                case 214 /* ForStatement */:
                case 215 /* ForInStatement */:
                case 216 /* ForOfStatement */:
                case 220 /* WithStatement */:
                case 221 /* SwitchStatement */:
                case 257 /* CaseClause */:
                case 258 /* DefaultClause */:
                case 222 /* LabeledStatement */:
                case 224 /* TryStatement */:
                case 260 /* CatchClause */:
                    return ts.forEachChild(node, traverse);
            }
        }
    }
    ts.forEachReturnStatement = forEachReturnStatement;
    function forEachYieldExpression(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 197 /* YieldExpression */:
                    visitor(node);
                    var operand = node.expression;
                    if (operand) {
                        traverse(operand);
                    }
                    return;
                case 232 /* EnumDeclaration */:
                case 230 /* InterfaceDeclaration */:
                case 233 /* ModuleDeclaration */:
                case 231 /* TypeAliasDeclaration */:
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                    // These are not allowed inside a generator now, but eventually they may be allowed
                    // as local types. Regardless, any yield statements contained within them should be
                    // skipped in this traversal.
                    return;
                default:
                    if (ts.isFunctionLike(node)) {
                        var name = node.name;
                        if (name && name.kind === 144 /* ComputedPropertyName */) {
                            // Note that we will not include methods/accessors of a class because they would require
                            // first descending into the class. This is by design.
                            traverse(name.expression);
                            return;
                        }
                    }
                    else if (!isPartOfTypeNode(node)) {
                        // This is the general case, which should include mostly expressions and statements.
                        // Also includes NodeArrays.
                        ts.forEachChild(node, traverse);
                    }
            }
        }
    }
    ts.forEachYieldExpression = forEachYieldExpression;
    /**
     * Gets the most likely element type for a TypeNode. This is not an exhaustive test
     * as it assumes a rest argument can only be an array type (either T[], or Array<T>).
     *
     * @param node The type node.
     */
    function getRestParameterElementType(node) {
        if (node && node.kind === 164 /* ArrayType */) {
            return node.elementType;
        }
        else if (node && node.kind === 159 /* TypeReference */) {
            return ts.singleOrUndefined(node.typeArguments);
        }
        else {
            return undefined;
        }
    }
    ts.getRestParameterElementType = getRestParameterElementType;
    function isVariableLike(node) {
        if (node) {
            switch (node.kind) {
                case 176 /* BindingElement */:
                case 264 /* EnumMember */:
                case 146 /* Parameter */:
                case 261 /* PropertyAssignment */:
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                case 262 /* ShorthandPropertyAssignment */:
                case 226 /* VariableDeclaration */:
                    return true;
            }
        }
        return false;
    }
    ts.isVariableLike = isVariableLike;
    function introducesArgumentsExoticObject(node) {
        switch (node.kind) {
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
            case 152 /* Constructor */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
                return true;
        }
        return false;
    }
    ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
    function unwrapInnermostStatementOfLabel(node, beforeUnwrapLabelCallback) {
        while (true) {
            if (beforeUnwrapLabelCallback) {
                beforeUnwrapLabelCallback(node);
            }
            if (node.statement.kind !== 222 /* LabeledStatement */) {
                return node.statement;
            }
            node = node.statement;
        }
    }
    ts.unwrapInnermostStatementOfLabel = unwrapInnermostStatementOfLabel;
    function isFunctionBlock(node) {
        return node && node.kind === 207 /* Block */ && ts.isFunctionLike(node.parent);
    }
    ts.isFunctionBlock = isFunctionBlock;
    function isObjectLiteralMethod(node) {
        return node && node.kind === 151 /* MethodDeclaration */ && node.parent.kind === 178 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralMethod = isObjectLiteralMethod;
    function isObjectLiteralOrClassExpressionMethod(node) {
        return node.kind === 151 /* MethodDeclaration */ &&
            (node.parent.kind === 178 /* ObjectLiteralExpression */ ||
                node.parent.kind === 199 /* ClassExpression */);
    }
    ts.isObjectLiteralOrClassExpressionMethod = isObjectLiteralOrClassExpressionMethod;
    function isIdentifierTypePredicate(predicate) {
        return predicate && predicate.kind === 1 /* Identifier */;
    }
    ts.isIdentifierTypePredicate = isIdentifierTypePredicate;
    function isThisTypePredicate(predicate) {
        return predicate && predicate.kind === 0 /* This */;
    }
    ts.isThisTypePredicate = isThisTypePredicate;
    function getPropertyAssignment(objectLiteral, key, key2) {
        return ts.filter(objectLiteral.properties, function (property) {
            if (property.kind === 261 /* PropertyAssignment */) {
                var propName = getTextOfPropertyName(property.name);
                return key === propName || (key2 && key2 === propName);
            }
        });
    }
    ts.getPropertyAssignment = getPropertyAssignment;
    function getContainingFunction(node) {
        return ts.findAncestor(node.parent, ts.isFunctionLike);
    }
    ts.getContainingFunction = getContainingFunction;
    function getContainingClass(node) {
        return ts.findAncestor(node.parent, ts.isClassLike);
    }
    ts.getContainingClass = getContainingClass;
    function getThisContainer(node, includeArrowFunctions) {
        while (true) {
            node = node.parent;
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 144 /* ComputedPropertyName */:
                    // If the grandparent node is an object literal (as opposed to a class),
                    // then the computed property is not a 'this' container.
                    // A computed property name in a class needs to be a this container
                    // so that we can error on it.
                    if (ts.isClassLike(node.parent.parent)) {
                        return node;
                    }
                    // If this is a computed property, then the parent should not
                    // make it a this container. The parent might be a property
                    // in an object literal, like a method or accessor. But in order for
                    // such a parent to be a this container, the reference must be in
                    // the *body* of the container.
                    node = node.parent;
                    break;
                case 147 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 146 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
                case 187 /* ArrowFunction */:
                    if (!includeArrowFunctions) {
                        continue;
                    }
                // falls through
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 233 /* ModuleDeclaration */:
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 152 /* Constructor */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 155 /* CallSignature */:
                case 156 /* ConstructSignature */:
                case 157 /* IndexSignature */:
                case 232 /* EnumDeclaration */:
                case 265 /* SourceFile */:
                    return node;
            }
        }
    }
    ts.getThisContainer = getThisContainer;
    function getNewTargetContainer(node) {
        var container = getThisContainer(node, /*includeArrowFunctions*/ false);
        if (container) {
            switch (container.kind) {
                case 152 /* Constructor */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                    return container;
            }
        }
        return undefined;
    }
    ts.getNewTargetContainer = getNewTargetContainer;
    /**
     * Given an super call/property node, returns the closest node where
     * - a super call/property access is legal in the node and not legal in the parent node the node.
     *   i.e. super call is legal in constructor but not legal in the class body.
     * - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
     * - a super call/property is definitely illegal in the container (but might be legal in some subnode)
     *   i.e. super property access is illegal in function declaration but can be legal in the statement list
     */
    function getSuperContainer(node, stopOnFunctions) {
        while (true) {
            node = node.parent;
            if (!node) {
                return node;
            }
            switch (node.kind) {
                case 144 /* ComputedPropertyName */:
                    node = node.parent;
                    break;
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    if (!stopOnFunctions) {
                        continue;
                    }
                // falls through
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 152 /* Constructor */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return node;
                case 147 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 146 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
            }
        }
    }
    ts.getSuperContainer = getSuperContainer;
    function getImmediatelyInvokedFunctionExpression(func) {
        if (func.kind === 186 /* FunctionExpression */ || func.kind === 187 /* ArrowFunction */) {
            var prev = func;
            var parent = func.parent;
            while (parent.kind === 185 /* ParenthesizedExpression */) {
                prev = parent;
                parent = parent.parent;
            }
            if (parent.kind === 181 /* CallExpression */ && parent.expression === prev) {
                return parent;
            }
        }
    }
    ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression;
    /**
     * Determines whether a node is a property or element access expression for super.
     */
    function isSuperProperty(node) {
        var kind = node.kind;
        return (kind === 179 /* PropertyAccessExpression */ || kind === 180 /* ElementAccessExpression */)
            && node.expression.kind === 97 /* SuperKeyword */;
    }
    ts.isSuperProperty = isSuperProperty;
    function getEntityNameFromTypeNode(node) {
        switch (node.kind) {
            case 159 /* TypeReference */:
                return node.typeName;
            case 201 /* ExpressionWithTypeArguments */:
                return isEntityNameExpression(node.expression)
                    ? node.expression
                    : undefined;
            case 71 /* Identifier */:
            case 143 /* QualifiedName */:
                return node;
        }
        return undefined;
    }
    ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
    function getInvokedExpression(node) {
        if (node.kind === 183 /* TaggedTemplateExpression */) {
            return node.tag;
        }
        else if (ts.isJsxOpeningLikeElement(node)) {
            return node.tagName;
        }
        // Will either be a CallExpression, NewExpression, or Decorator.
        return node.expression;
    }
    ts.getInvokedExpression = getInvokedExpression;
    function nodeCanBeDecorated(node) {
        switch (node.kind) {
            case 229 /* ClassDeclaration */:
                // classes are valid targets
                return true;
            case 149 /* PropertyDeclaration */:
                // property declarations are valid if their parent is a class declaration.
                return node.parent.kind === 229 /* ClassDeclaration */;
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 151 /* MethodDeclaration */:
                // if this method has a body and its parent is a class declaration, this is a valid target.
                return node.body !== undefined
                    && node.parent.kind === 229 /* ClassDeclaration */;
            case 146 /* Parameter */:
                // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
                return node.parent.body !== undefined
                    && (node.parent.kind === 152 /* Constructor */
                        || node.parent.kind === 151 /* MethodDeclaration */
                        || node.parent.kind === 154 /* SetAccessor */)
                    && node.parent.parent.kind === 229 /* ClassDeclaration */;
        }
        return false;
    }
    ts.nodeCanBeDecorated = nodeCanBeDecorated;
    function nodeIsDecorated(node) {
        return node.decorators !== undefined
            && nodeCanBeDecorated(node);
    }
    ts.nodeIsDecorated = nodeIsDecorated;
    function nodeOrChildIsDecorated(node) {
        return nodeIsDecorated(node) || childIsDecorated(node);
    }
    ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
    function childIsDecorated(node) {
        switch (node.kind) {
            case 229 /* ClassDeclaration */:
                return ts.forEach(node.members, nodeOrChildIsDecorated);
            case 151 /* MethodDeclaration */:
            case 154 /* SetAccessor */:
                return ts.forEach(node.parameters, nodeIsDecorated);
        }
    }
    ts.childIsDecorated = childIsDecorated;
    function isJSXTagName(node) {
        var parent = node.parent;
        if (parent.kind === 251 /* JsxOpeningElement */ ||
            parent.kind === 250 /* JsxSelfClosingElement */ ||
            parent.kind === 252 /* JsxClosingElement */) {
            return parent.tagName === node;
        }
        return false;
    }
    ts.isJSXTagName = isJSXTagName;
    function isPartOfExpression(node) {
        switch (node.kind) {
            case 97 /* SuperKeyword */:
            case 95 /* NullKeyword */:
            case 101 /* TrueKeyword */:
            case 86 /* FalseKeyword */:
            case 12 /* RegularExpressionLiteral */:
            case 177 /* ArrayLiteralExpression */:
            case 178 /* ObjectLiteralExpression */:
            case 179 /* PropertyAccessExpression */:
            case 180 /* ElementAccessExpression */:
            case 181 /* CallExpression */:
            case 182 /* NewExpression */:
            case 183 /* TaggedTemplateExpression */:
            case 202 /* AsExpression */:
            case 184 /* TypeAssertionExpression */:
            case 203 /* NonNullExpression */:
            case 185 /* ParenthesizedExpression */:
            case 186 /* FunctionExpression */:
            case 199 /* ClassExpression */:
            case 187 /* ArrowFunction */:
            case 190 /* VoidExpression */:
            case 188 /* DeleteExpression */:
            case 189 /* TypeOfExpression */:
            case 192 /* PrefixUnaryExpression */:
            case 193 /* PostfixUnaryExpression */:
            case 194 /* BinaryExpression */:
            case 195 /* ConditionalExpression */:
            case 198 /* SpreadElement */:
            case 196 /* TemplateExpression */:
            case 13 /* NoSubstitutionTemplateLiteral */:
            case 200 /* OmittedExpression */:
            case 249 /* JsxElement */:
            case 250 /* JsxSelfClosingElement */:
            case 197 /* YieldExpression */:
            case 191 /* AwaitExpression */:
            case 204 /* MetaProperty */:
                return true;
            case 143 /* QualifiedName */:
                while (node.parent.kind === 143 /* QualifiedName */) {
                    node = node.parent;
                }
                return node.parent.kind === 162 /* TypeQuery */ || isJSXTagName(node);
            case 71 /* Identifier */:
                if (node.parent.kind === 162 /* TypeQuery */ || isJSXTagName(node)) {
                    return true;
                }
            // falls through
            case 8 /* NumericLiteral */:
            case 9 /* StringLiteral */:
            case 99 /* ThisKeyword */:
                return isInExpressionContext(node);
            default:
                return false;
        }
    }
    ts.isPartOfExpression = isPartOfExpression;
    function isInExpressionContext(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 226 /* VariableDeclaration */:
            case 146 /* Parameter */:
            case 149 /* PropertyDeclaration */:
            case 148 /* PropertySignature */:
            case 264 /* EnumMember */:
            case 261 /* PropertyAssignment */:
            case 176 /* BindingElement */:
                return parent.initializer === node;
            case 210 /* ExpressionStatement */:
            case 211 /* IfStatement */:
            case 212 /* DoStatement */:
            case 213 /* WhileStatement */:
            case 219 /* ReturnStatement */:
            case 220 /* WithStatement */:
            case 221 /* SwitchStatement */:
            case 257 /* CaseClause */:
            case 223 /* ThrowStatement */:
                return parent.expression === node;
            case 214 /* ForStatement */:
                var forStatement = parent;
                return (forStatement.initializer === node && forStatement.initializer.kind !== 227 /* VariableDeclarationList */) ||
                    forStatement.condition === node ||
                    forStatement.incrementor === node;
            case 215 /* ForInStatement */:
            case 216 /* ForOfStatement */:
                var forInStatement = parent;
                return (forInStatement.initializer === node && forInStatement.initializer.kind !== 227 /* VariableDeclarationList */) ||
                    forInStatement.expression === node;
            case 184 /* TypeAssertionExpression */:
            case 202 /* AsExpression */:
                return node === parent.expression;
            case 205 /* TemplateSpan */:
                return node === parent.expression;
            case 144 /* ComputedPropertyName */:
                return node === parent.expression;
            case 147 /* Decorator */:
            case 256 /* JsxExpression */:
            case 255 /* JsxSpreadAttribute */:
            case 263 /* SpreadAssignment */:
                return true;
            case 201 /* ExpressionWithTypeArguments */:
                return parent.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
            default:
                return isPartOfExpression(parent);
        }
    }
    ts.isInExpressionContext = isInExpressionContext;
    function isExternalModuleImportEqualsDeclaration(node) {
        return node.kind === 237 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 248 /* ExternalModuleReference */;
    }
    ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
    function getExternalModuleImportEqualsDeclarationExpression(node) {
        ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
        return node.moduleReference.expression;
    }
    ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
    function isInternalModuleImportEqualsDeclaration(node) {
        return node.kind === 237 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 248 /* ExternalModuleReference */;
    }
    ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
    function isSourceFileJavaScript(file) {
        return isInJavaScriptFile(file);
    }
    ts.isSourceFileJavaScript = isSourceFileJavaScript;
    function isInJavaScriptFile(node) {
        return node && !!(node.flags & 65536 /* JavaScriptFile */);
    }
    ts.isInJavaScriptFile = isInJavaScriptFile;
    function isInJSDoc(node) {
        return node && !!(node.flags & 1048576 /* JSDoc */);
    }
    ts.isInJSDoc = isInJSDoc;
    function isJSDocIndexSignature(node) {
        return ts.isTypeReferenceNode(node) &&
            ts.isIdentifier(node.typeName) &&
            node.typeName.escapedText === "Object" &&
            node.typeArguments && node.typeArguments.length === 2 &&
            (node.typeArguments[0].kind === 136 /* StringKeyword */ || node.typeArguments[0].kind === 133 /* NumberKeyword */);
    }
    ts.isJSDocIndexSignature = isJSDocIndexSignature;
    /**
     * Returns true if the node is a CallExpression to the identifier 'require' with
     * exactly one argument (of the form 'require("name")').
     * This function does not test if the node is in a JavaScript file or not.
     */
    function isRequireCall(callExpression, checkArgumentIsStringLiteral) {
        if (callExpression.kind !== 181 /* CallExpression */) {
            return false;
        }
        var _a = callExpression, expression = _a.expression, args = _a.arguments;
        if (expression.kind !== 71 /* Identifier */ || expression.escapedText !== "require") {
            return false;
        }
        if (args.length !== 1) {
            return false;
        }
        var arg = args[0];
        return !checkArgumentIsStringLiteral || arg.kind === 9 /* StringLiteral */ || arg.kind === 13 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isRequireCall = isRequireCall;
    function isSingleOrDoubleQuote(charCode) {
        return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */;
    }
    ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote;
    function isStringDoubleQuoted(string, sourceFile) {
        return getSourceTextOfNodeFromSourceFile(sourceFile, string).charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isStringDoubleQuoted = isStringDoubleQuoted;
    /**
     * Returns true if the node is a variable declaration whose initializer is a function expression.
     * This function does not test if the node is in a JavaScript file or not.
     */
    function isDeclarationOfFunctionOrClassExpression(s) {
        if (s.valueDeclaration && s.valueDeclaration.kind === 226 /* VariableDeclaration */) {
            var declaration = s.valueDeclaration;
            return declaration.initializer && (declaration.initializer.kind === 186 /* FunctionExpression */ || declaration.initializer.kind === 199 /* ClassExpression */);
        }
        return false;
    }
    ts.isDeclarationOfFunctionOrClassExpression = isDeclarationOfFunctionOrClassExpression;
    function getRightMostAssignedExpression(node) {
        while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) {
            node = node.right;
        }
        return node;
    }
    ts.getRightMostAssignedExpression = getRightMostAssignedExpression;
    function isExportsIdentifier(node) {
        return ts.isIdentifier(node) && node.escapedText === "exports";
    }
    ts.isExportsIdentifier = isExportsIdentifier;
    function isModuleExportsPropertyAccessExpression(node) {
        return ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText === "module" && node.name.escapedText === "exports";
    }
    ts.isModuleExportsPropertyAccessExpression = isModuleExportsPropertyAccessExpression;
    /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
    /// assignments we treat as special in the binder
    function getSpecialPropertyAssignmentKind(expr) {
        if (!isInJavaScriptFile(expr)) {
            return 0 /* None */;
        }
        if (expr.operatorToken.kind !== 58 /* EqualsToken */ || expr.left.kind !== 179 /* PropertyAccessExpression */) {
            return 0 /* None */;
        }
        var lhs = expr.left;
        if (lhs.expression.kind === 71 /* Identifier */) {
            var lhsId = lhs.expression;
            if (lhsId.escapedText === "exports") {
                // exports.name = expr
                return 1 /* ExportsProperty */;
            }
            else if (lhsId.escapedText === "module" && lhs.name.escapedText === "exports") {
                // module.exports = expr
                return 2 /* ModuleExports */;
            }
            else {
                // F.x = expr
                return 5 /* Property */;
            }
        }
        else if (lhs.expression.kind === 99 /* ThisKeyword */) {
            return 4 /* ThisProperty */;
        }
        else if (lhs.expression.kind === 179 /* PropertyAccessExpression */) {
            // chained dot, e.g. x.y.z = expr; this var is the 'x.y' part
            var innerPropertyAccess = lhs.expression;
            if (innerPropertyAccess.expression.kind === 71 /* Identifier */) {
                // module.exports.name = expr
                var innerPropertyAccessIdentifier = innerPropertyAccess.expression;
                if (innerPropertyAccessIdentifier.escapedText === "module" && innerPropertyAccess.name.escapedText === "exports") {
                    return 1 /* ExportsProperty */;
                }
                if (innerPropertyAccess.name.escapedText === "prototype") {
                    return 3 /* PrototypeProperty */;
                }
            }
        }
        return 0 /* None */;
    }
    ts.getSpecialPropertyAssignmentKind = getSpecialPropertyAssignmentKind;
    function getExternalModuleName(node) {
        if (node.kind === 238 /* ImportDeclaration */) {
            return node.moduleSpecifier;
        }
        if (node.kind === 237 /* ImportEqualsDeclaration */) {
            var reference = node.moduleReference;
            if (reference.kind === 248 /* ExternalModuleReference */) {
                return reference.expression;
            }
        }
        if (node.kind === 244 /* ExportDeclaration */) {
            return node.moduleSpecifier;
        }
        if (isModuleWithStringLiteralName(node)) {
            return node.name;
        }
    }
    ts.getExternalModuleName = getExternalModuleName;
    function getNamespaceDeclarationNode(node) {
        if (node.kind === 237 /* ImportEqualsDeclaration */) {
            return node;
        }
        var importClause = node.importClause;
        if (importClause && importClause.namedBindings && importClause.namedBindings.kind === 240 /* NamespaceImport */) {
            return importClause.namedBindings;
        }
    }
    ts.getNamespaceDeclarationNode = getNamespaceDeclarationNode;
    function isDefaultImport(node) {
        return node.kind === 238 /* ImportDeclaration */
            && node.importClause
            && !!node.importClause.name;
    }
    ts.isDefaultImport = isDefaultImport;
    function hasQuestionToken(node) {
        if (node) {
            switch (node.kind) {
                case 146 /* Parameter */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 262 /* ShorthandPropertyAssignment */:
                case 261 /* PropertyAssignment */:
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    return node.questionToken !== undefined;
            }
        }
        return false;
    }
    ts.hasQuestionToken = hasQuestionToken;
    function isJSDocConstructSignature(node) {
        return node.kind === 273 /* JSDocFunctionType */ &&
            node.parameters.length > 0 &&
            node.parameters[0].name &&
            node.parameters[0].name.escapedText === "new";
    }
    ts.isJSDocConstructSignature = isJSDocConstructSignature;
    function getAllJSDocs(node) {
        if (ts.isJSDocTypedefTag(node)) {
            return [node.parent];
        }
        return getJSDocCommentsAndTags(node);
    }
    ts.getAllJSDocs = getAllJSDocs;
    function getSourceOfAssignment(node) {
        return ts.isExpressionStatement(node) &&
            node.expression && ts.isBinaryExpression(node.expression) &&
            node.expression.operatorToken.kind === 58 /* EqualsToken */ &&
            node.expression.right;
    }
    ts.getSourceOfAssignment = getSourceOfAssignment;
    function getSingleInitializerOfVariableStatement(node, child) {
        return ts.isVariableStatement(node) &&
            node.declarationList.declarations.length > 0 &&
            (!child || node.declarationList.declarations[0].initializer === child) &&
            node.declarationList.declarations[0].initializer;
    }
    ts.getSingleInitializerOfVariableStatement = getSingleInitializerOfVariableStatement;
    function getSingleVariableOfVariableStatement(node, child) {
        return ts.isVariableStatement(node) &&
            node.declarationList.declarations.length > 0 &&
            (!child || node.declarationList.declarations[0] === child) &&
            node.declarationList.declarations[0];
    }
    ts.getSingleVariableOfVariableStatement = getSingleVariableOfVariableStatement;
    function getNestedModuleDeclaration(node) {
        return node.kind === 233 /* ModuleDeclaration */ &&
            node.body &&
            node.body.kind === 233 /* ModuleDeclaration */ &&
            node.body;
    }
    ts.getNestedModuleDeclaration = getNestedModuleDeclaration;
    function getJSDocCommentsAndTags(node) {
        var result;
        getJSDocCommentsAndTagsWorker(node);
        return result || ts.emptyArray;
        function getJSDocCommentsAndTagsWorker(node) {
            var parent = node.parent;
            // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
            // /**
            //   * @param {number} name
            //   * @returns {number}
            //   */
            // var x = function(name) { return name.length; }
            if (parent && (parent.kind === 261 /* PropertyAssignment */ || getNestedModuleDeclaration(parent))) {
                getJSDocCommentsAndTagsWorker(parent);
            }
            if (parent && parent.parent &&
                (getSingleVariableOfVariableStatement(parent.parent, node) || getSourceOfAssignment(parent.parent))) {
                getJSDocCommentsAndTagsWorker(parent.parent);
            }
            if (parent && parent.parent && parent.parent.parent && getSingleInitializerOfVariableStatement(parent.parent.parent, node)) {
                getJSDocCommentsAndTagsWorker(parent.parent.parent);
            }
            // Pull parameter comments from declaring function as well
            if (node.kind === 146 /* Parameter */) {
                result = ts.addRange(result, ts.getJSDocParameterTags(node));
            }
            if (isVariableLike(node) && node.initializer && ts.hasJSDocNodes(node.initializer)) {
                result = ts.addRange(result, node.initializer.jsDoc);
            }
            if (ts.hasJSDocNodes(node)) {
                result = ts.addRange(result, node.jsDoc);
            }
        }
    }
    ts.getJSDocCommentsAndTags = getJSDocCommentsAndTags;
    /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
    function getParameterSymbolFromJSDoc(node) {
        if (node.symbol) {
            return node.symbol;
        }
        if (!ts.isIdentifier(node.name)) {
            return undefined;
        }
        var name = node.name.escapedText;
        var host = getJSDocHost(node);
        var decl = getSourceOfAssignment(host) ||
            getSingleInitializerOfVariableStatement(host) ||
            getSingleVariableOfVariableStatement(host) ||
            getNestedModuleDeclaration(host) ||
            host;
        if (decl && ts.isFunctionLike(decl)) {
            var parameter = ts.find(decl.parameters, function (p) { return p.name.kind === 71 /* Identifier */ && p.name.escapedText === name; });
            return parameter && parameter.symbol;
        }
    }
    ts.getParameterSymbolFromJSDoc = getParameterSymbolFromJSDoc;
    function getJSDocHost(node) {
        ts.Debug.assert(node.parent.kind === 275 /* JSDocComment */);
        return node.parent.parent;
    }
    ts.getJSDocHost = getJSDocHost;
    function getTypeParameterFromJsDoc(node) {
        var name = node.name.escapedText;
        var typeParameters = node.parent.parent.parent.typeParameters;
        return ts.find(typeParameters, function (p) { return p.name.escapedText === name; });
    }
    ts.getTypeParameterFromJsDoc = getTypeParameterFromJsDoc;
    function hasRestParameter(s) {
        var last = ts.lastOrUndefined(s.parameters);
        return last && isRestParameter(last);
    }
    ts.hasRestParameter = hasRestParameter;
    function isRestParameter(node) {
        return node.dotDotDotToken !== undefined;
    }
    ts.isRestParameter = isRestParameter;
    var AssignmentKind;
    (function (AssignmentKind) {
        AssignmentKind[AssignmentKind["None"] = 0] = "None";
        AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite";
        AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound";
    })(AssignmentKind = ts.AssignmentKind || (ts.AssignmentKind = {}));
    function getAssignmentTargetKind(node) {
        var parent = node.parent;
        while (true) {
            switch (parent.kind) {
                case 194 /* BinaryExpression */:
                    var binaryOperator = parent.operatorToken.kind;
                    return isAssignmentOperator(binaryOperator) && parent.left === node ?
                        binaryOperator === 58 /* EqualsToken */ ? 1 /* Definite */ : 2 /* Compound */ :
                        0 /* None */;
                case 192 /* PrefixUnaryExpression */:
                case 193 /* PostfixUnaryExpression */:
                    var unaryOperator = parent.operator;
                    return unaryOperator === 43 /* PlusPlusToken */ || unaryOperator === 44 /* MinusMinusToken */ ? 2 /* Compound */ : 0 /* None */;
                case 215 /* ForInStatement */:
                case 216 /* ForOfStatement */:
                    return parent.initializer === node ? 1 /* Definite */ : 0 /* None */;
                case 185 /* ParenthesizedExpression */:
                case 177 /* ArrayLiteralExpression */:
                case 198 /* SpreadElement */:
                    node = parent;
                    break;
                case 262 /* ShorthandPropertyAssignment */:
                    if (parent.name !== node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                case 261 /* PropertyAssignment */:
                    if (parent.name === node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                default:
                    return 0 /* None */;
            }
            parent = node.parent;
        }
    }
    ts.getAssignmentTargetKind = getAssignmentTargetKind;
    // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
    // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
    // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'.
    // (Note that `p` is not a target in the above examples, only `a`.)
    function isAssignmentTarget(node) {
        return getAssignmentTargetKind(node) !== 0 /* None */;
    }
    ts.isAssignmentTarget = isAssignmentTarget;
    // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
    function isDeleteTarget(node) {
        if (node.kind !== 179 /* PropertyAccessExpression */ && node.kind !== 180 /* ElementAccessExpression */) {
            return false;
        }
        node = node.parent;
        while (node && node.kind === 185 /* ParenthesizedExpression */) {
            node = node.parent;
        }
        return node && node.kind === 188 /* DeleteExpression */;
    }
    ts.isDeleteTarget = isDeleteTarget;
    function isNodeDescendantOf(node, ancestor) {
        while (node) {
            if (node === ancestor)
                return true;
            node = node.parent;
        }
        return false;
    }
    ts.isNodeDescendantOf = isNodeDescendantOf;
    function isInAmbientContext(node) {
        while (node) {
            if (hasModifier(node, 2 /* Ambient */) || (node.kind === 265 /* SourceFile */ && node.isDeclarationFile)) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    ts.isInAmbientContext = isInAmbientContext;
    // True if the given identifier, string literal, or number literal is the name of a declaration node
    function isDeclarationName(name) {
        switch (name.kind) {
            case 71 /* Identifier */:
            case 9 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                return ts.isDeclaration(name.parent) && name.parent.name === name;
            default:
                return false;
        }
    }
    ts.isDeclarationName = isDeclarationName;
    /* @internal */
    // See GH#16030
    function isAnyDeclarationName(name) {
        switch (name.kind) {
            case 71 /* Identifier */:
            case 9 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                if (ts.isDeclaration(name.parent)) {
                    return name.parent.name === name;
                }
                var binExp = name.parent.parent;
                return ts.isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== 0 /* None */ && ts.getNameOfDeclaration(binExp) === name;
            default:
                return false;
        }
    }
    ts.isAnyDeclarationName = isAnyDeclarationName;
    function isLiteralComputedPropertyDeclarationName(node) {
        return (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) &&
            node.parent.kind === 144 /* ComputedPropertyName */ &&
            ts.isDeclaration(node.parent.parent);
    }
    ts.isLiteralComputedPropertyDeclarationName = isLiteralComputedPropertyDeclarationName;
    // Return true if the given identifier is classified as an IdentifierName
    function isIdentifierName(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 149 /* PropertyDeclaration */:
            case 148 /* PropertySignature */:
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 264 /* EnumMember */:
            case 261 /* PropertyAssignment */:
            case 179 /* PropertyAccessExpression */:
                // Name in member declaration or property name in property access
                return parent.name === node;
            case 143 /* QualifiedName */:
                // Name on right hand side of dot in a type query
                if (parent.right === node) {
                    while (parent.kind === 143 /* QualifiedName */) {
                        parent = parent.parent;
                    }
                    return parent.kind === 162 /* TypeQuery */;
                }
                return false;
            case 176 /* BindingElement */:
            case 242 /* ImportSpecifier */:
                // Property name in binding element or import specifier
                return parent.propertyName === node;
            case 246 /* ExportSpecifier */:
            case 253 /* JsxAttribute */:
                // Any name in an export specifier or JSX Attribute
                return true;
        }
        return false;
    }
    ts.isIdentifierName = isIdentifierName;
    // An alias symbol is created by one of the following declarations:
    // import <symbol> = ...
    // import <symbol> from ...
    // import * as <symbol> from ...
    // import { x as <symbol> } from ...
    // export { x as <symbol> } from ...
    // export = <EntityNameExpression>
    // export default <EntityNameExpression>
    function isAliasSymbolDeclaration(node) {
        return node.kind === 237 /* ImportEqualsDeclaration */ ||
            node.kind === 236 /* NamespaceExportDeclaration */ ||
            node.kind === 239 /* ImportClause */ && !!node.name ||
            node.kind === 240 /* NamespaceImport */ ||
            node.kind === 242 /* ImportSpecifier */ ||
            node.kind === 246 /* ExportSpecifier */ ||
            node.kind === 243 /* ExportAssignment */ && exportAssignmentIsAlias(node);
    }
    ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
    function exportAssignmentIsAlias(node) {
        return isEntityNameExpression(node.expression);
    }
    ts.exportAssignmentIsAlias = exportAssignmentIsAlias;
    function getClassExtendsHeritageClauseElement(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 85 /* ExtendsKeyword */);
        return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
    }
    ts.getClassExtendsHeritageClauseElement = getClassExtendsHeritageClauseElement;
    function getClassImplementsHeritageClauseElements(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 108 /* ImplementsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements;
    function getInterfaceBaseTypeNodes(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 85 /* ExtendsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
    function getHeritageClause(clauses, kind) {
        if (clauses) {
            for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
                var clause = clauses_1[_i];
                if (clause.token === kind) {
                    return clause;
                }
            }
        }
        return undefined;
    }
    ts.getHeritageClause = getHeritageClause;
    function tryResolveScriptReference(host, sourceFile, reference) {
        if (!host.getCompilerOptions().noResolve) {
            var referenceFileName = ts.isRootedDiskPath(reference.fileName) ? reference.fileName : ts.combinePaths(ts.getDirectoryPath(sourceFile.fileName), reference.fileName);
            return host.getSourceFile(referenceFileName);
        }
    }
    ts.tryResolveScriptReference = tryResolveScriptReference;
    function getAncestor(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.getAncestor = getAncestor;
    function getFileReferenceFromReferencePath(comment, commentRange) {
        var simpleReferenceRegEx = /^\/\/\/\s*<reference\s+/gim;
        var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim");
        if (simpleReferenceRegEx.test(comment)) {
            if (isNoDefaultLibRegEx.test(comment)) {
                return { isNoDefaultLib: true };
            }
            else {
                var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment);
                var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment);
                var match = refMatchResult || refLibResult;
                if (match) {
                    var pos = commentRange.pos + match[1].length + match[2].length;
                    return {
                        fileReference: {
                            pos: pos,
                            end: pos + match[3].length,
                            fileName: match[3]
                        },
                        isNoDefaultLib: false,
                        isTypeReferenceDirective: !!refLibResult
                    };
                }
                return {
                    diagnosticMessage: ts.Diagnostics.Invalid_reference_directive_syntax,
                    isNoDefaultLib: false
                };
            }
        }
        return undefined;
    }
    ts.getFileReferenceFromReferencePath = getFileReferenceFromReferencePath;
    function isKeyword(token) {
        return 72 /* FirstKeyword */ <= token && token <= 142 /* LastKeyword */;
    }
    ts.isKeyword = isKeyword;
    function isTrivia(token) {
        return 2 /* FirstTriviaToken */ <= token && token <= 7 /* LastTriviaToken */;
    }
    ts.isTrivia = isTrivia;
    var FunctionFlags;
    (function (FunctionFlags) {
        FunctionFlags[FunctionFlags["Normal"] = 0] = "Normal";
        FunctionFlags[FunctionFlags["Generator"] = 1] = "Generator";
        FunctionFlags[FunctionFlags["Async"] = 2] = "Async";
        FunctionFlags[FunctionFlags["Invalid"] = 4] = "Invalid";
        FunctionFlags[FunctionFlags["AsyncGenerator"] = 3] = "AsyncGenerator";
    })(FunctionFlags = ts.FunctionFlags || (ts.FunctionFlags = {}));
    function getFunctionFlags(node) {
        if (!node) {
            return 4 /* Invalid */;
        }
        var flags = 0 /* Normal */;
        switch (node.kind) {
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
            case 151 /* MethodDeclaration */:
                if (node.asteriskToken) {
                    flags |= 1 /* Generator */;
                }
            // falls through
            case 187 /* ArrowFunction */:
                if (hasModifier(node, 256 /* Async */)) {
                    flags |= 2 /* Async */;
                }
                break;
        }
        if (!node.body) {
            flags |= 4 /* Invalid */;
        }
        return flags;
    }
    ts.getFunctionFlags = getFunctionFlags;
    function isAsyncFunction(node) {
        switch (node.kind) {
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
            case 187 /* ArrowFunction */:
            case 151 /* MethodDeclaration */:
                return node.body !== undefined
                    && node.asteriskToken === undefined
                    && hasModifier(node, 256 /* Async */);
        }
        return false;
    }
    ts.isAsyncFunction = isAsyncFunction;
    function isStringOrNumericLiteral(node) {
        var kind = node.kind;
        return kind === 9 /* StringLiteral */
            || kind === 8 /* NumericLiteral */;
    }
    ts.isStringOrNumericLiteral = isStringOrNumericLiteral;
    /**
     * A declaration has a dynamic name if both of the following are true:
     *   1. The declaration has a computed property name
     *   2. The computed name is *not* expressed as Symbol.<name>, where name
     *      is a property of the Symbol constructor that denotes a built in
     *      Symbol.
     */
    function hasDynamicName(declaration) {
        var name = ts.getNameOfDeclaration(declaration);
        return name && isDynamicName(name);
    }
    ts.hasDynamicName = hasDynamicName;
    function isDynamicName(name) {
        return name.kind === 144 /* ComputedPropertyName */ &&
            !isStringOrNumericLiteral(name.expression) &&
            !isWellKnownSymbolSyntactically(name.expression);
    }
    ts.isDynamicName = isDynamicName;
    /**
     * Checks if the expression is of the form:
     *    Symbol.name
     * where Symbol is literally the word "Symbol", and name is any identifierName
     */
    function isWellKnownSymbolSyntactically(node) {
        return ts.isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
    }
    ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
    function getPropertyNameForPropertyNameNode(name) {
        if (name.kind === 71 /* Identifier */) {
            return name.escapedText;
        }
        if (name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */) {
            return escapeLeadingUnderscores(name.text);
        }
        if (name.kind === 144 /* ComputedPropertyName */) {
            var nameExpression = name.expression;
            if (isWellKnownSymbolSyntactically(nameExpression)) {
                return getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
            }
            else if (nameExpression.kind === 9 /* StringLiteral */ || nameExpression.kind === 8 /* NumericLiteral */) {
                return escapeLeadingUnderscores(nameExpression.text);
            }
        }
        return undefined;
    }
    ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
    function getTextOfIdentifierOrLiteral(node) {
        if (node) {
            if (node.kind === 71 /* Identifier */) {
                return ts.idText(node);
            }
            if (node.kind === 9 /* StringLiteral */ ||
                node.kind === 8 /* NumericLiteral */) {
                return node.text;
            }
        }
        return undefined;
    }
    ts.getTextOfIdentifierOrLiteral = getTextOfIdentifierOrLiteral;
    function getEscapedTextOfIdentifierOrLiteral(node) {
        if (node) {
            if (node.kind === 71 /* Identifier */) {
                return node.escapedText;
            }
            if (node.kind === 9 /* StringLiteral */ ||
                node.kind === 8 /* NumericLiteral */) {
                return escapeLeadingUnderscores(node.text);
            }
        }
        return undefined;
    }
    ts.getEscapedTextOfIdentifierOrLiteral = getEscapedTextOfIdentifierOrLiteral;
    function getPropertyNameForKnownSymbolName(symbolName) {
        return "__@" + symbolName;
    }
    ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
    /**
     * Includes the word "Symbol" with unicode escapes
     */
    function isESSymbolIdentifier(node) {
        return node.kind === 71 /* Identifier */ && node.escapedText === "Symbol";
    }
    ts.isESSymbolIdentifier = isESSymbolIdentifier;
    function isPushOrUnshiftIdentifier(node) {
        return node.escapedText === "push" || node.escapedText === "unshift";
    }
    ts.isPushOrUnshiftIdentifier = isPushOrUnshiftIdentifier;
    function isParameterDeclaration(node) {
        var root = getRootDeclaration(node);
        return root.kind === 146 /* Parameter */;
    }
    ts.isParameterDeclaration = isParameterDeclaration;
    function getRootDeclaration(node) {
        while (node.kind === 176 /* BindingElement */) {
            node = node.parent.parent;
        }
        return node;
    }
    ts.getRootDeclaration = getRootDeclaration;
    function nodeStartsNewLexicalEnvironment(node) {
        var kind = node.kind;
        return kind === 152 /* Constructor */
            || kind === 186 /* FunctionExpression */
            || kind === 228 /* FunctionDeclaration */
            || kind === 187 /* ArrowFunction */
            || kind === 151 /* MethodDeclaration */
            || kind === 153 /* GetAccessor */
            || kind === 154 /* SetAccessor */
            || kind === 233 /* ModuleDeclaration */
            || kind === 265 /* SourceFile */;
    }
    ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
    function nodeIsSynthesized(range) {
        return ts.positionIsSynthesized(range.pos)
            || ts.positionIsSynthesized(range.end);
    }
    ts.nodeIsSynthesized = nodeIsSynthesized;
    function getOriginalSourceFile(sourceFile) {
        return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile;
    }
    ts.getOriginalSourceFile = getOriginalSourceFile;
    var Associativity;
    (function (Associativity) {
        Associativity[Associativity["Left"] = 0] = "Left";
        Associativity[Associativity["Right"] = 1] = "Right";
    })(Associativity = ts.Associativity || (ts.Associativity = {}));
    function getExpressionAssociativity(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 182 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorAssociativity(expression.kind, operator, hasArguments);
    }
    ts.getExpressionAssociativity = getExpressionAssociativity;
    function getOperatorAssociativity(kind, operator, hasArguments) {
        switch (kind) {
            case 182 /* NewExpression */:
                return hasArguments ? 0 /* Left */ : 1 /* Right */;
            case 192 /* PrefixUnaryExpression */:
            case 189 /* TypeOfExpression */:
            case 190 /* VoidExpression */:
            case 188 /* DeleteExpression */:
            case 191 /* AwaitExpression */:
            case 195 /* ConditionalExpression */:
            case 197 /* YieldExpression */:
                return 1 /* Right */;
            case 194 /* BinaryExpression */:
                switch (operator) {
                    case 40 /* AsteriskAsteriskToken */:
                    case 58 /* EqualsToken */:
                    case 59 /* PlusEqualsToken */:
                    case 60 /* MinusEqualsToken */:
                    case 62 /* AsteriskAsteriskEqualsToken */:
                    case 61 /* AsteriskEqualsToken */:
                    case 63 /* SlashEqualsToken */:
                    case 64 /* PercentEqualsToken */:
                    case 65 /* LessThanLessThanEqualsToken */:
                    case 66 /* GreaterThanGreaterThanEqualsToken */:
                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 68 /* AmpersandEqualsToken */:
                    case 70 /* CaretEqualsToken */:
                    case 69 /* BarEqualsToken */:
                        return 1 /* Right */;
                }
        }
        return 0 /* Left */;
    }
    ts.getOperatorAssociativity = getOperatorAssociativity;
    function getExpressionPrecedence(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 182 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorPrecedence(expression.kind, operator, hasArguments);
    }
    ts.getExpressionPrecedence = getExpressionPrecedence;
    function getOperator(expression) {
        if (expression.kind === 194 /* BinaryExpression */) {
            return expression.operatorToken.kind;
        }
        else if (expression.kind === 192 /* PrefixUnaryExpression */ || expression.kind === 193 /* PostfixUnaryExpression */) {
            return expression.operator;
        }
        else {
            return expression.kind;
        }
    }
    ts.getOperator = getOperator;
    function getOperatorPrecedence(nodeKind, operatorKind, hasArguments) {
        switch (nodeKind) {
            case 99 /* ThisKeyword */:
            case 97 /* SuperKeyword */:
            case 71 /* Identifier */:
            case 95 /* NullKeyword */:
            case 101 /* TrueKeyword */:
            case 86 /* FalseKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* StringLiteral */:
            case 177 /* ArrayLiteralExpression */:
            case 178 /* ObjectLiteralExpression */:
            case 186 /* FunctionExpression */:
            case 187 /* ArrowFunction */:
            case 199 /* ClassExpression */:
            case 249 /* JsxElement */:
            case 250 /* JsxSelfClosingElement */:
            case 12 /* RegularExpressionLiteral */:
            case 13 /* NoSubstitutionTemplateLiteral */:
            case 196 /* TemplateExpression */:
            case 185 /* ParenthesizedExpression */:
            case 200 /* OmittedExpression */:
                return 19;
            case 183 /* TaggedTemplateExpression */:
            case 179 /* PropertyAccessExpression */:
            case 180 /* ElementAccessExpression */:
                return 18;
            case 182 /* NewExpression */:
                return hasArguments ? 18 : 17;
            case 181 /* CallExpression */:
                return 17;
            case 193 /* PostfixUnaryExpression */:
                return 16;
            case 192 /* PrefixUnaryExpression */:
            case 189 /* TypeOfExpression */:
            case 190 /* VoidExpression */:
            case 188 /* DeleteExpression */:
            case 191 /* AwaitExpression */:
                return 15;
            case 194 /* BinaryExpression */:
                switch (operatorKind) {
                    case 51 /* ExclamationToken */:
                    case 52 /* TildeToken */:
                        return 15;
                    case 40 /* AsteriskAsteriskToken */:
                    case 39 /* AsteriskToken */:
                    case 41 /* SlashToken */:
                    case 42 /* PercentToken */:
                        return 14;
                    case 37 /* PlusToken */:
                    case 38 /* MinusToken */:
                        return 13;
                    case 45 /* LessThanLessThanToken */:
                    case 46 /* GreaterThanGreaterThanToken */:
                    case 47 /* GreaterThanGreaterThanGreaterThanToken */:
                        return 12;
                    case 27 /* LessThanToken */:
                    case 30 /* LessThanEqualsToken */:
                    case 29 /* GreaterThanToken */:
                    case 31 /* GreaterThanEqualsToken */:
                    case 92 /* InKeyword */:
                    case 93 /* InstanceOfKeyword */:
                        return 11;
                    case 32 /* EqualsEqualsToken */:
                    case 34 /* EqualsEqualsEqualsToken */:
                    case 33 /* ExclamationEqualsToken */:
                    case 35 /* ExclamationEqualsEqualsToken */:
                        return 10;
                    case 48 /* AmpersandToken */:
                        return 9;
                    case 50 /* CaretToken */:
                        return 8;
                    case 49 /* BarToken */:
                        return 7;
                    case 53 /* AmpersandAmpersandToken */:
                        return 6;
                    case 54 /* BarBarToken */:
                        return 5;
                    case 58 /* EqualsToken */:
                    case 59 /* PlusEqualsToken */:
                    case 60 /* MinusEqualsToken */:
                    case 62 /* AsteriskAsteriskEqualsToken */:
                    case 61 /* AsteriskEqualsToken */:
                    case 63 /* SlashEqualsToken */:
                    case 64 /* PercentEqualsToken */:
                    case 65 /* LessThanLessThanEqualsToken */:
                    case 66 /* GreaterThanGreaterThanEqualsToken */:
                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 68 /* AmpersandEqualsToken */:
                    case 70 /* CaretEqualsToken */:
                    case 69 /* BarEqualsToken */:
                        return 3;
                    case 26 /* CommaToken */:
                        return 0;
                    default:
                        return -1;
                }
            case 195 /* ConditionalExpression */:
                return 4;
            case 197 /* YieldExpression */:
                return 2;
            case 198 /* SpreadElement */:
                return 1;
            case 289 /* CommaListExpression */:
                return 0;
            default:
                return -1;
        }
    }
    ts.getOperatorPrecedence = getOperatorPrecedence;
    function createDiagnosticCollection() {
        var nonFileDiagnostics = [];
        var fileDiagnostics = ts.createMap();
        var diagnosticsModified = false;
        var modificationCount = 0;
        return {
            add: add,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getDiagnostics: getDiagnostics,
            getModificationCount: getModificationCount,
            reattachFileDiagnostics: reattachFileDiagnostics
        };
        function getModificationCount() {
            return modificationCount;
        }
        function reattachFileDiagnostics(newFile) {
            ts.forEach(fileDiagnostics.get(newFile.fileName), function (diagnostic) { return diagnostic.file = newFile; });
        }
        function add(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
                if (!diagnostics) {
                    diagnostics = [];
                    fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
                }
            }
            else {
                diagnostics = nonFileDiagnostics;
            }
            diagnostics.push(diagnostic);
            diagnosticsModified = true;
            modificationCount++;
        }
        function getGlobalDiagnostics() {
            sortAndDeduplicate();
            return nonFileDiagnostics;
        }
        function getDiagnostics(fileName) {
            sortAndDeduplicate();
            if (fileName) {
                return fileDiagnostics.get(fileName) || [];
            }
            var allDiagnostics = [];
            function pushDiagnostic(d) {
                allDiagnostics.push(d);
            }
            ts.forEach(nonFileDiagnostics, pushDiagnostic);
            fileDiagnostics.forEach(function (diagnostics) {
                ts.forEach(diagnostics, pushDiagnostic);
            });
            return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        }
        function sortAndDeduplicate() {
            if (!diagnosticsModified) {
                return;
            }
            diagnosticsModified = false;
            nonFileDiagnostics = ts.sortAndDeduplicateDiagnostics(nonFileDiagnostics);
            fileDiagnostics.forEach(function (diagnostics, key) {
                fileDiagnostics.set(key, ts.sortAndDeduplicateDiagnostics(diagnostics));
            });
        }
    }
    ts.createDiagnosticCollection = createDiagnosticCollection;
    // This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
    // the language service. These characters should be escaped when printing, and if any characters are added,
    // the map below must be updated. Note that this regexp *does not* include the 'delete' character.
    // There is no reason for this other than that JSON.stringify does not handle it either.
    var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var escapedCharsMap = ts.createMapFromTemplate({
        "\0": "\\0",
        "\t": "\\t",
        "\v": "\\v",
        "\f": "\\f",
        "\b": "\\b",
        "\r": "\\r",
        "\n": "\\n",
        "\\": "\\\\",
        "\"": "\\\"",
        "\'": "\\\'",
        "\`": "\\\`",
        "\u2028": "\\u2028",
        "\u2029": "\\u2029",
        "\u0085": "\\u0085" // nextLine
    });
    var escapedNullRegExp = /\\0[0-9]/g;
    /**
     * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
     * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
     * Note that this doesn't actually wrap the input in double quotes.
     */
    function escapeString(s, quoteChar) {
        var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp :
            quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp :
                doubleQuoteEscapedCharsRegExp;
        return s.replace(escapedCharsRegExp, getReplacement).replace(escapedNullRegExp, nullReplacement);
    }
    ts.escapeString = escapeString;
    function nullReplacement(c) {
        return "\\x00" + c.charAt(c.length - 1);
    }
    function getReplacement(c) {
        return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
    }
    function isIntrinsicJsxName(name) {
        // An escaped identifier had a leading underscore prior to being escaped, which would return true
        // The escape adds an extra underscore which does not change the result
        var ch = name.substr(0, 1);
        return ch.toLowerCase() === ch;
    }
    ts.isIntrinsicJsxName = isIntrinsicJsxName;
    function get16BitUnicodeEscapeSequence(charCode) {
        var hexCharCode = charCode.toString(16).toUpperCase();
        var paddedHexCode = ("0000" + hexCharCode).slice(-4);
        return "\\u" + paddedHexCode;
    }
    var nonAsciiCharacters = /[^\u0000-\u007F]/g;
    function escapeNonAsciiString(s, quoteChar) {
        s = escapeString(s, quoteChar);
        // Replace non-ASCII characters with '\uNNNN' escapes if any exist.
        // Otherwise just return the original string.
        return nonAsciiCharacters.test(s) ?
            s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) :
            s;
    }
    ts.escapeNonAsciiString = escapeNonAsciiString;
    var indentStrings = ["", "    "];
    function getIndentString(level) {
        if (indentStrings[level] === undefined) {
            indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
        }
        return indentStrings[level];
    }
    ts.getIndentString = getIndentString;
    function getIndentSize() {
        return indentStrings[1].length;
    }
    ts.getIndentSize = getIndentSize;
    function createTextWriter(newLine) {
        var output;
        var indent;
        var lineStart;
        var lineCount;
        var linePos;
        function write(s) {
            if (s && s.length) {
                if (lineStart) {
                    output += getIndentString(indent);
                    lineStart = false;
                }
                output += s;
            }
        }
        function reset() {
            output = "";
            indent = 0;
            lineStart = true;
            lineCount = 0;
            linePos = 0;
        }
        function rawWrite(s) {
            if (s !== undefined) {
                if (lineStart) {
                    lineStart = false;
                }
                output += s;
            }
        }
        function writeLiteral(s) {
            if (s && s.length) {
                write(s);
                var lineStartsOfS = ts.computeLineStarts(s);
                if (lineStartsOfS.length > 1) {
                    lineCount = lineCount + lineStartsOfS.length - 1;
                    linePos = output.length - s.length + ts.lastOrUndefined(lineStartsOfS);
                }
            }
        }
        function writeLine() {
            if (!lineStart) {
                output += newLine;
                lineCount++;
                linePos = output.length;
                lineStart = true;
            }
        }
        function writeTextOfNode(text, node) {
            write(getTextOfNodeFromSourceText(text, node));
        }
        reset();
        return {
            write: write,
            rawWrite: rawWrite,
            writeTextOfNode: writeTextOfNode,
            writeLiteral: writeLiteral,
            writeLine: writeLine,
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            getIndent: function () { return indent; },
            getTextPos: function () { return output.length; },
            getLine: function () { return lineCount + 1; },
            getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
            getText: function () { return output; },
            isAtStartOfLine: function () { return lineStart; },
            reset: reset
        };
    }
    ts.createTextWriter = createTextWriter;
    function getResolvedExternalModuleName(host, file) {
        return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
    }
    ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
    function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
        var file = resolver.getExternalModuleFileFromDeclaration(declaration);
        if (!file || file.isDeclarationFile) {
            return undefined;
        }
        return getResolvedExternalModuleName(host, file);
    }
    ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
    /**
     * Resolves a local path to a path which is absolute to the base of the emit
     */
    function getExternalModuleNameFromPath(host, fileName) {
        var getCanonicalFileName = function (f) { return host.getCanonicalFileName(f); };
        var dir = ts.toPath(host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
        var filePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
        var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
        return ts.removeFileExtension(relativePath);
    }
    ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
    function getOwnEmitOutputFilePath(sourceFile, host, extension) {
        var compilerOptions = host.getCompilerOptions();
        var emitOutputFilePathWithoutExtension;
        if (compilerOptions.outDir) {
            emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
        }
        else {
            emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
        }
        return emitOutputFilePathWithoutExtension + extension;
    }
    ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
    function getDeclarationEmitOutputFilePath(sourceFile, host) {
        var options = host.getCompilerOptions();
        var outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified
        var path = outputDir
            ? getSourceFilePathInNewDir(sourceFile, host, outputDir)
            : sourceFile.fileName;
        return ts.removeFileExtension(path) + ".d.ts" /* Dts */;
    }
    ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath;
    /**
     * Gets the source files that are expected to have an emit output.
     *
     * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support
     * transformations.
     *
     * @param host An EmitHost.
     * @param targetSourceFile An optional target source file to emit.
     */
    function getSourceFilesToEmit(host, targetSourceFile) {
        var options = host.getCompilerOptions();
        var isSourceFileFromExternalLibrary = function (file) { return host.isSourceFileFromExternalLibrary(file); };
        if (options.outFile || options.out) {
            var moduleKind = ts.getEmitModuleKind(options);
            var moduleEmitEnabled_1 = moduleKind === ts.ModuleKind.AMD || moduleKind === ts.ModuleKind.System;
            // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
            return ts.filter(host.getSourceFiles(), function (sourceFile) {
                return (moduleEmitEnabled_1 || !ts.isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary);
            });
        }
        else {
            var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
            return ts.filter(sourceFiles, function (sourceFile) { return sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary); });
        }
    }
    ts.getSourceFilesToEmit = getSourceFilesToEmit;
    /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */
    function sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary) {
        return !(options.noEmitForJsFiles && isSourceFileJavaScript(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile);
    }
    ts.sourceFileMayBeEmitted = sourceFileMayBeEmitted;
    function getSourceFilePathInNewDir(sourceFile, host, newDirPath) {
        var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory());
        var commonSourceDirectory = host.getCommonSourceDirectory();
        var isSourceFileInCommonSourceDirectory = host.getCanonicalFileName(sourceFilePath).indexOf(host.getCanonicalFileName(commonSourceDirectory)) === 0;
        sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
        return ts.combinePaths(newDirPath, sourceFilePath);
    }
    ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
    function writeFile(host, diagnostics, fileName, data, writeByteOrderMark, sourceFiles) {
        host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
            diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
        }, sourceFiles);
    }
    ts.writeFile = writeFile;
    function getLineOfLocalPosition(currentSourceFile, pos) {
        return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
    }
    ts.getLineOfLocalPosition = getLineOfLocalPosition;
    function getLineOfLocalPositionFromLineMap(lineMap, pos) {
        return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
    }
    ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
    function getFirstConstructorWithBody(node) {
        return ts.forEach(node.members, function (member) {
            if (member.kind === 152 /* Constructor */ && nodeIsPresent(member.body)) {
                return member;
            }
        });
    }
    ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
    function getSetAccessorValueParameter(accessor) {
        if (accessor && accessor.parameters.length > 0) {
            var hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
            return accessor.parameters[hasThis ? 1 : 0];
        }
    }
    /** Get the type annotation for the value parameter. */
    function getSetAccessorTypeAnnotationNode(accessor) {
        var parameter = getSetAccessorValueParameter(accessor);
        return parameter && parameter.type;
    }
    ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
    function getThisParameter(signature) {
        if (signature.parameters.length) {
            var thisParameter = signature.parameters[0];
            if (parameterIsThisKeyword(thisParameter)) {
                return thisParameter;
            }
        }
    }
    ts.getThisParameter = getThisParameter;
    function parameterIsThisKeyword(parameter) {
        return isThisIdentifier(parameter.name);
    }
    ts.parameterIsThisKeyword = parameterIsThisKeyword;
    function isThisIdentifier(node) {
        return node && node.kind === 71 /* Identifier */ && identifierIsThisKeyword(node);
    }
    ts.isThisIdentifier = isThisIdentifier;
    function identifierIsThisKeyword(id) {
        return id.originalKeywordKind === 99 /* ThisKeyword */;
    }
    ts.identifierIsThisKeyword = identifierIsThisKeyword;
    function getAllAccessorDeclarations(declarations, accessor) {
        var firstAccessor;
        var secondAccessor;
        var getAccessor;
        var setAccessor;
        if (hasDynamicName(accessor)) {
            firstAccessor = accessor;
            if (accessor.kind === 153 /* GetAccessor */) {
                getAccessor = accessor;
            }
            else if (accessor.kind === 154 /* SetAccessor */) {
                setAccessor = accessor;
            }
            else {
                ts.Debug.fail("Accessor has wrong kind");
            }
        }
        else {
            ts.forEach(declarations, function (member) {
                if ((member.kind === 153 /* GetAccessor */ || member.kind === 154 /* SetAccessor */)
                    && hasModifier(member, 32 /* Static */) === hasModifier(accessor, 32 /* Static */)) {
                    var memberName = getPropertyNameForPropertyNameNode(member.name);
                    var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
                    if (memberName === accessorName) {
                        if (!firstAccessor) {
                            firstAccessor = member;
                        }
                        else if (!secondAccessor) {
                            secondAccessor = member;
                        }
                        if (member.kind === 153 /* GetAccessor */ && !getAccessor) {
                            getAccessor = member;
                        }
                        if (member.kind === 154 /* SetAccessor */ && !setAccessor) {
                            setAccessor = member;
                        }
                    }
                }
            });
        }
        return {
            firstAccessor: firstAccessor,
            secondAccessor: secondAccessor,
            getAccessor: getAccessor,
            setAccessor: setAccessor
        };
    }
    ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
    /**
     * Gets the effective type annotation of a variable, parameter, or property. If the node was
     * parsed in a JavaScript file, gets the type annotation from JSDoc.
     */
    function getEffectiveTypeAnnotationNode(node, checkJSDoc) {
        if (node.type) {
            return node.type;
        }
        if (checkJSDoc || isInJavaScriptFile(node)) {
            return ts.getJSDocType(node);
        }
    }
    ts.getEffectiveTypeAnnotationNode = getEffectiveTypeAnnotationNode;
    /**
     * Gets the effective return type annotation of a signature. If the node was parsed in a
     * JavaScript file, gets the return type annotation from JSDoc.
     */
    function getEffectiveReturnTypeNode(node, checkJSDoc) {
        if (node.type) {
            return node.type;
        }
        if (checkJSDoc || isInJavaScriptFile(node)) {
            return ts.getJSDocReturnType(node);
        }
    }
    ts.getEffectiveReturnTypeNode = getEffectiveReturnTypeNode;
    /**
     * Gets the effective type parameters. If the node was parsed in a
     * JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
     */
    function getEffectiveTypeParameterDeclarations(node, checkJSDoc) {
        if (node.typeParameters) {
            return node.typeParameters;
        }
        if (checkJSDoc || isInJavaScriptFile(node)) {
            var templateTag = ts.getJSDocTemplateTag(node);
            return templateTag && templateTag.typeParameters;
        }
    }
    ts.getEffectiveTypeParameterDeclarations = getEffectiveTypeParameterDeclarations;
    /**
     * Gets the effective type annotation of the value parameter of a set accessor. If the node
     * was parsed in a JavaScript file, gets the type annotation from JSDoc.
     */
    function getEffectiveSetAccessorTypeAnnotationNode(node, checkJSDoc) {
        var parameter = getSetAccessorValueParameter(node);
        return parameter && getEffectiveTypeAnnotationNode(parameter, checkJSDoc);
    }
    ts.getEffectiveSetAccessorTypeAnnotationNode = getEffectiveSetAccessorTypeAnnotationNode;
    function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
        emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
    }
    ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
    function emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, pos, leadingComments) {
        // If the leading comments start on different line than the start of node, write new line
        if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentsOfPosition = emitNewLineBeforeLeadingCommentsOfPosition;
    function emitNewLineBeforeLeadingCommentOfPosition(lineMap, writer, pos, commentPos) {
        // If the leading comments start on different line than the start of node, write new line
        if (pos !== commentPos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentOfPosition = emitNewLineBeforeLeadingCommentOfPosition;
    function emitComments(text, lineMap, writer, comments, leadingSeparator, trailingSeparator, newLine, writeComment) {
        if (comments && comments.length > 0) {
            if (leadingSeparator) {
                writer.write(" ");
            }
            var emitInterveningSeparator = false;
            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                var comment = comments_1[_i];
                if (emitInterveningSeparator) {
                    writer.write(" ");
                    emitInterveningSeparator = false;
                }
                writeComment(text, lineMap, writer, comment.pos, comment.end, newLine);
                if (comment.hasTrailingNewLine) {
                    writer.writeLine();
                }
                else {
                    emitInterveningSeparator = true;
                }
            }
            if (emitInterveningSeparator && trailingSeparator) {
                writer.write(" ");
            }
        }
    }
    ts.emitComments = emitComments;
    /**
     * Detached comment is a comment at the top of file or function body that is separated from
     * the next statement by space.
     */
    function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
        var leadingComments;
        var currentDetachedCommentInfo;
        if (removeComments) {
            // removeComments is true, only reserve pinned comment at the top of file
            // For example:
            //      /*! Pinned Comment */
            //
            //      var x = 10;
            if (node.pos === 0) {
                leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal);
            }
        }
        else {
            // removeComments is false, just get detached as normal and bypass the process to filter comment
            leadingComments = ts.getLeadingCommentRanges(text, node.pos);
        }
        if (leadingComments) {
            var detachedComments = [];
            var lastComment = void 0;
            for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
                var comment = leadingComments_1[_i];
                if (lastComment) {
                    var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
                    var commentLine = getLineOfLocalPositionFromLineMap(lineMap, 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.
                        break;
                    }
                }
                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 = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end);
                var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
                if (nodeLine >= lastCommentLine + 2) {
                    // Valid detachedComments
                    emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
                    emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
                    currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
                }
            }
        }
        return currentDetachedCommentInfo;
        function isPinnedCommentLocal(comment) {
            return isPinnedComment(text, comment);
        }
    }
    ts.emitDetachedComments = emitDetachedComments;
    function writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine) {
        if (text.charCodeAt(commentPos + 1) === 42 /* asterisk */) {
            var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, commentPos);
            var lineCount = lineMap.length;
            var firstCommentLineIndent = void 0;
            for (var pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) {
                var nextLineStart = (currentLine + 1) === lineCount
                    ? text.length + 1
                    : lineMap[currentLine + 1];
                if (pos !== commentPos) {
                    // If we are not emitting first line, we need to write the spaces to adjust the alignment
                    if (firstCommentLineIndent === undefined) {
                        firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], commentPos);
                    }
                    // These are number of spaces writer is going to write at current indent
                    var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
                    // Number of spaces we want to be writing
                    // eg: Assume writer indent
                    // module m {
                    //         /* starts at character 9 this is line 1
                    //    * starts at character pos 4 line                        --1  = 8 - 8 + 3
                    //   More left indented comment */                            --2  = 8 - 8 + 2
                    //     class c { }
                    // }
                    // module m {
                    //     /* this is line 1 -- Assume current writer indent 8
                    //      * line                                                --3 = 8 - 4 + 5
                    //            More right indented comment */                  --4 = 8 - 4 + 11
                    //     class c { }
                    // }
                    var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
                    if (spacesToEmit > 0) {
                        var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
                        var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
                        // Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
                        writer.rawWrite(indentSizeSpaceString);
                        // Emit the single spaces (in eg: 1: 3 spaces, 2: 2 spaces, 3: 1 space, 4: 3 spaces)
                        while (numberOfSingleSpacesToEmit) {
                            writer.rawWrite(" ");
                            numberOfSingleSpacesToEmit--;
                        }
                    }
                    else {
                        // No spaces to emit write empty string
                        writer.rawWrite("");
                    }
                }
                // Write the comment line text
                writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart);
                pos = nextLineStart;
            }
        }
        else {
            // Single line comment of style //....
            writer.write(text.substring(commentPos, commentEnd));
        }
    }
    ts.writeCommentRange = writeCommentRange;
    function writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart) {
        var end = Math.min(commentEnd, nextLineStart - 1);
        var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
        if (currentLineText) {
            // trimmed forward and ending spaces text
            writer.write(currentLineText);
            if (end !== commentEnd) {
                writer.writeLine();
            }
        }
        else {
            // Empty string - make sure we write empty line
            writer.writeLiteral(newLine);
        }
    }
    function calculateIndent(text, pos, end) {
        var currentLineIndent = 0;
        for (; pos < end && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) {
            if (text.charCodeAt(pos) === 9 /* tab */) {
                // Tabs = TabSize = indent size and go to next tabStop
                currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
            }
            else {
                // Single space
                currentLineIndent++;
            }
        }
        return currentLineIndent;
    }
    function hasModifiers(node) {
        return getModifierFlags(node) !== 0 /* None */;
    }
    ts.hasModifiers = hasModifiers;
    function hasModifier(node, flags) {
        return !!getSelectedModifierFlags(node, flags);
    }
    ts.hasModifier = hasModifier;
    function getSelectedModifierFlags(node, flags) {
        return getModifierFlags(node) & flags;
    }
    ts.getSelectedModifierFlags = getSelectedModifierFlags;
    function getModifierFlags(node) {
        if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) {
            return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */;
        }
        var flags = getModifierFlagsNoCache(node);
        node.modifierFlagsCache = flags | 536870912 /* HasComputedFlags */;
        return flags;
    }
    ts.getModifierFlags = getModifierFlags;
    /* @internal */
    function getModifierFlagsNoCache(node) {
        var flags = 0 /* None */;
        if (node.modifiers) {
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                flags |= modifierToFlag(modifier.kind);
            }
        }
        if (node.flags & 4 /* NestedNamespace */ || (node.kind === 71 /* Identifier */ && node.isInJSDocNamespace)) {
            flags |= 1 /* Export */;
        }
        return flags;
    }
    ts.getModifierFlagsNoCache = getModifierFlagsNoCache;
    function modifierToFlag(token) {
        switch (token) {
            case 115 /* StaticKeyword */: return 32 /* Static */;
            case 114 /* PublicKeyword */: return 4 /* Public */;
            case 113 /* ProtectedKeyword */: return 16 /* Protected */;
            case 112 /* PrivateKeyword */: return 8 /* Private */;
            case 117 /* AbstractKeyword */: return 128 /* Abstract */;
            case 84 /* ExportKeyword */: return 1 /* Export */;
            case 124 /* DeclareKeyword */: return 2 /* Ambient */;
            case 76 /* ConstKeyword */: return 2048 /* Const */;
            case 79 /* DefaultKeyword */: return 512 /* Default */;
            case 120 /* AsyncKeyword */: return 256 /* Async */;
            case 131 /* ReadonlyKeyword */: return 64 /* Readonly */;
        }
        return 0 /* None */;
    }
    ts.modifierToFlag = modifierToFlag;
    function isLogicalOperator(token) {
        return token === 54 /* BarBarToken */
            || token === 53 /* AmpersandAmpersandToken */
            || token === 51 /* ExclamationToken */;
    }
    ts.isLogicalOperator = isLogicalOperator;
    function isAssignmentOperator(token) {
        return token >= 58 /* FirstAssignment */ && token <= 70 /* LastAssignment */;
    }
    ts.isAssignmentOperator = isAssignmentOperator;
    /** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
    function tryGetClassExtendingExpressionWithTypeArguments(node) {
        if (node.kind === 201 /* ExpressionWithTypeArguments */ &&
            node.parent.token === 85 /* ExtendsKeyword */ &&
            ts.isClassLike(node.parent.parent)) {
            return node.parent.parent;
        }
    }
    ts.tryGetClassExtendingExpressionWithTypeArguments = tryGetClassExtendingExpressionWithTypeArguments;
    function isAssignmentExpression(node, excludeCompoundAssignment) {
        return ts.isBinaryExpression(node)
            && (excludeCompoundAssignment
                ? node.operatorToken.kind === 58 /* EqualsToken */
                : isAssignmentOperator(node.operatorToken.kind))
            && ts.isLeftHandSideExpression(node.left);
    }
    ts.isAssignmentExpression = isAssignmentExpression;
    function isDestructuringAssignment(node) {
        if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
            var kind = node.left.kind;
            return kind === 178 /* ObjectLiteralExpression */
                || kind === 177 /* ArrayLiteralExpression */;
        }
        return false;
    }
    ts.isDestructuringAssignment = isDestructuringAssignment;
    function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
        return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
    }
    ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
    function isExpressionWithTypeArgumentsInClassImplementsClause(node) {
        return node.kind === 201 /* ExpressionWithTypeArguments */
            && isEntityNameExpression(node.expression)
            && node.parent
            && node.parent.token === 108 /* ImplementsKeyword */
            && node.parent.parent
            && ts.isClassLike(node.parent.parent);
    }
    ts.isExpressionWithTypeArgumentsInClassImplementsClause = isExpressionWithTypeArgumentsInClassImplementsClause;
    function isEntityNameExpression(node) {
        return node.kind === 71 /* Identifier */ ||
            node.kind === 179 /* PropertyAccessExpression */ && isEntityNameExpression(node.expression);
    }
    ts.isEntityNameExpression = isEntityNameExpression;
    function isRightSideOfQualifiedNameOrPropertyAccess(node) {
        return (node.parent.kind === 143 /* QualifiedName */ && node.parent.right === node) ||
            (node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node);
    }
    ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
    function isEmptyObjectLiteral(expression) {
        return expression.kind === 178 /* ObjectLiteralExpression */ &&
            expression.properties.length === 0;
    }
    ts.isEmptyObjectLiteral = isEmptyObjectLiteral;
    function isEmptyArrayLiteral(expression) {
        return expression.kind === 177 /* ArrayLiteralExpression */ &&
            expression.elements.length === 0;
    }
    ts.isEmptyArrayLiteral = isEmptyArrayLiteral;
    function getLocalSymbolForExportDefault(symbol) {
        return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
    }
    ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
    function isExportDefaultSymbol(symbol) {
        return symbol && ts.length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], 512 /* Default */);
    }
    /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
    function tryExtractTypeScriptExtension(fileName) {
        return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension;
    /**
     * Replace each instance of non-ascii characters by one, two, three, or four escape sequences
     * representing the UTF-8 encoding of the character, and return the expanded char code list.
     */
    function getExpandedCharCodes(input) {
        var output = [];
        var length = input.length;
        for (var i = 0; i < length; i++) {
            var charCode = input.charCodeAt(i);
            // handel utf8
            if (charCode < 0x80) {
                output.push(charCode);
            }
            else if (charCode < 0x800) {
                output.push((charCode >> 6) | 192);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x10000) {
                output.push((charCode >> 12) | 224);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x20000) {
                output.push((charCode >> 18) | 240);
                output.push(((charCode >> 12) & 63) | 128);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else {
                ts.Debug.assert(false, "Unexpected code point");
            }
        }
        return output;
    }
    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    /**
     * Converts a string to a base-64 encoded ASCII string.
     */
    function convertToBase64(input) {
        var result = "";
        var charCodes = getExpandedCharCodes(input);
        var i = 0;
        var length = charCodes.length;
        var byte1, byte2, byte3, byte4;
        while (i < length) {
            // Convert every 6-bits in the input 3 character points
            // into a base64 digit
            byte1 = charCodes[i] >> 2;
            byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
            byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
            byte4 = charCodes[i + 2] & 63;
            // We are out of characters in the input, set the extra
            // digits to 64 (padding character).
            if (i + 1 >= length) {
                byte3 = byte4 = 64;
            }
            else if (i + 2 >= length) {
                byte4 = 64;
            }
            // Write to the output
            result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
            i += 3;
        }
        return result;
    }
    ts.convertToBase64 = convertToBase64;
    var carriageReturnLineFeed = "\r\n";
    var lineFeed = "\n";
    function getNewLineCharacter(options, system) {
        switch (options.newLine) {
            case 0 /* CarriageReturnLineFeed */:
                return carriageReturnLineFeed;
            case 1 /* LineFeed */:
                return lineFeed;
        }
        return system ? system.newLine : ts.sys ? ts.sys.newLine : carriageReturnLineFeed;
    }
    ts.getNewLineCharacter = getNewLineCharacter;
    /**
     * Formats an enum value as a string for debugging and debug assertions.
     */
    function formatEnum(value, enumObject, isFlags) {
        if (value === void 0) { value = 0; }
        var members = getEnumMembers(enumObject);
        if (value === 0) {
            return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
        }
        if (isFlags) {
            var result = "";
            var remainingFlags = value;
            for (var i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) {
                var _a = members[i], enumValue = _a[0], enumName = _a[1];
                if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
                    remainingFlags &= ~enumValue;
                    result = "" + enumName + (result ? ", " : "") + result;
                }
            }
            if (remainingFlags === 0) {
                return result;
            }
        }
        else {
            for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
                var _b = members_1[_i], enumValue = _b[0], enumName = _b[1];
                if (enumValue === value) {
                    return enumName;
                }
            }
        }
        return value.toString();
    }
    function getEnumMembers(enumObject) {
        var result = [];
        for (var name in enumObject) {
            var value = enumObject[name];
            if (typeof value === "number") {
                result.push([value, name]);
            }
        }
        return ts.stableSort(result, function (x, y) { return ts.compareValues(x[0], y[0]); });
    }
    function formatSyntaxKind(kind) {
        return formatEnum(kind, ts.SyntaxKind, /*isFlags*/ false);
    }
    ts.formatSyntaxKind = formatSyntaxKind;
    function formatModifierFlags(flags) {
        return formatEnum(flags, ts.ModifierFlags, /*isFlags*/ true);
    }
    ts.formatModifierFlags = formatModifierFlags;
    function formatTransformFlags(flags) {
        return formatEnum(flags, ts.TransformFlags, /*isFlags*/ true);
    }
    ts.formatTransformFlags = formatTransformFlags;
    function formatEmitFlags(flags) {
        return formatEnum(flags, ts.EmitFlags, /*isFlags*/ true);
    }
    ts.formatEmitFlags = formatEmitFlags;
    function formatSymbolFlags(flags) {
        return formatEnum(flags, ts.SymbolFlags, /*isFlags*/ true);
    }
    ts.formatSymbolFlags = formatSymbolFlags;
    function formatTypeFlags(flags) {
        return formatEnum(flags, ts.TypeFlags, /*isFlags*/ true);
    }
    ts.formatTypeFlags = formatTypeFlags;
    function formatObjectFlags(flags) {
        return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true);
    }
    ts.formatObjectFlags = formatObjectFlags;
    /**
     * Creates a new TextRange from the provided pos and end.
     *
     * @param pos The start position.
     * @param end The end position.
     */
    function createRange(pos, end) {
        return { pos: pos, end: end };
    }
    ts.createRange = createRange;
    /**
     * Creates a new TextRange from a provided range with a new end position.
     *
     * @param range A TextRange.
     * @param end The new end position.
     */
    function moveRangeEnd(range, end) {
        return createRange(range.pos, end);
    }
    ts.moveRangeEnd = moveRangeEnd;
    /**
     * Creates a new TextRange from a provided range with a new start position.
     *
     * @param range A TextRange.
     * @param pos The new Start position.
     */
    function moveRangePos(range, pos) {
        return createRange(pos, range.end);
    }
    ts.moveRangePos = moveRangePos;
    /**
     * Moves the start position of a range past any decorators.
     */
    function moveRangePastDecorators(node) {
        return node.decorators && node.decorators.length > 0
            ? moveRangePos(node, node.decorators.end)
            : node;
    }
    ts.moveRangePastDecorators = moveRangePastDecorators;
    /**
     * Moves the start position of a range past any decorators or modifiers.
     */
    function moveRangePastModifiers(node) {
        return node.modifiers && node.modifiers.length > 0
            ? moveRangePos(node, node.modifiers.end)
            : moveRangePastDecorators(node);
    }
    ts.moveRangePastModifiers = moveRangePastModifiers;
    /**
     * Determines whether a TextRange has the same start and end positions.
     *
     * @param range A TextRange.
     */
    function isCollapsedRange(range) {
        return range.pos === range.end;
    }
    ts.isCollapsedRange = isCollapsedRange;
    /**
     * Creates a new TextRange for a token at the provides start position.
     *
     * @param pos The start position.
     * @param token The token.
     */
    function createTokenRange(pos, token) {
        return createRange(pos, pos + ts.tokenToString(token).length);
    }
    ts.createTokenRange = createTokenRange;
    function rangeIsOnSingleLine(range, sourceFile) {
        return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile);
    }
    ts.rangeIsOnSingleLine = rangeIsOnSingleLine;
    function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), getStartPositionOfRange(range2, sourceFile), sourceFile);
    }
    ts.rangeStartPositionsAreOnSameLine = rangeStartPositionsAreOnSameLine;
    function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, range2.end, sourceFile);
    }
    ts.rangeEndPositionsAreOnSameLine = rangeEndPositionsAreOnSameLine;
    function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), range2.end, sourceFile);
    }
    ts.rangeStartIsOnSameLineAsRangeEnd = rangeStartIsOnSameLineAsRangeEnd;
    function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile), sourceFile);
    }
    ts.rangeEndIsOnSameLineAsRangeStart = rangeEndIsOnSameLineAsRangeStart;
    function positionsAreOnSameLine(pos1, pos2, sourceFile) {
        return pos1 === pos2 ||
            getLineOfLocalPosition(sourceFile, pos1) === getLineOfLocalPosition(sourceFile, pos2);
    }
    ts.positionsAreOnSameLine = positionsAreOnSameLine;
    function getStartPositionOfRange(range, sourceFile) {
        return ts.positionIsSynthesized(range.pos) ? -1 : ts.skipTrivia(sourceFile.text, range.pos);
    }
    ts.getStartPositionOfRange = getStartPositionOfRange;
    /**
     * Determines whether a name was originally the declaration name of an enum or namespace
     * declaration.
     */
    function isDeclarationNameOfEnumOrNamespace(node) {
        var parseNode = ts.getParseTreeNode(node);
        if (parseNode) {
            switch (parseNode.parent.kind) {
                case 232 /* EnumDeclaration */:
                case 233 /* ModuleDeclaration */:
                    return parseNode === parseNode.parent.name;
            }
        }
        return false;
    }
    ts.isDeclarationNameOfEnumOrNamespace = isDeclarationNameOfEnumOrNamespace;
    function getInitializedVariables(node) {
        return ts.filter(node.declarations, isInitializedVariable);
    }
    ts.getInitializedVariables = getInitializedVariables;
    function isInitializedVariable(node) {
        return node.initializer !== undefined;
    }
    function isWatchSet(options) {
        // Firefox has Object.prototype.watch
        return options.watch && options.hasOwnProperty("watch");
    }
    ts.isWatchSet = isWatchSet;
    function getCheckFlags(symbol) {
        return symbol.flags & 33554432 /* Transient */ ? symbol.checkFlags : 0;
    }
    ts.getCheckFlags = getCheckFlags;
    function getDeclarationModifierFlagsFromSymbol(s) {
        if (s.valueDeclaration) {
            var flags = ts.getCombinedModifierFlags(s.valueDeclaration);
            return s.parent && s.parent.flags & 32 /* Class */ ? flags : flags & ~28 /* AccessibilityModifier */;
        }
        if (getCheckFlags(s) & 6 /* Synthetic */) {
            var checkFlags = s.checkFlags;
            var accessModifier = checkFlags & 256 /* ContainsPrivate */ ? 8 /* Private */ :
                checkFlags & 64 /* ContainsPublic */ ? 4 /* Public */ :
                    16 /* Protected */;
            var staticModifier = checkFlags & 512 /* ContainsStatic */ ? 32 /* Static */ : 0;
            return accessModifier | staticModifier;
        }
        if (s.flags & 4194304 /* Prototype */) {
            return 4 /* Public */ | 32 /* Static */;
        }
        return 0;
    }
    ts.getDeclarationModifierFlagsFromSymbol = getDeclarationModifierFlagsFromSymbol;
    function levenshtein(s1, s2) {
        var previous = new Array(s2.length + 1);
        var current = new Array(s2.length + 1);
        for (var i = 0; i < s2.length + 1; i++) {
            previous[i] = i;
            current[i] = -1;
        }
        for (var i = 1; i < s1.length + 1; i++) {
            current[0] = i;
            for (var j = 1; j < s2.length + 1; j++) {
                current[j] = Math.min(previous[j] + 1, current[j - 1] + 1, previous[j - 1] + (s1[i - 1] === s2[j - 1] ? 0 : 2));
            }
            // shift current back to previous, and then reuse previous' array
            var tmp = previous;
            previous = current;
            current = tmp;
        }
        return previous[previous.length - 1];
    }
    ts.levenshtein = levenshtein;
    function skipAlias(symbol, checker) {
        return symbol.flags & 2097152 /* Alias */ ? checker.getAliasedSymbol(symbol) : symbol;
    }
    ts.skipAlias = skipAlias;
    /** See comment on `declareModuleMember` in `binder.ts`. */
    function getCombinedLocalAndExportSymbolFlags(symbol) {
        return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
    }
    ts.getCombinedLocalAndExportSymbolFlags = getCombinedLocalAndExportSymbolFlags;
    function isWriteOnlyAccess(node) {
        return accessKind(node) === 1 /* Write */;
    }
    ts.isWriteOnlyAccess = isWriteOnlyAccess;
    function isWriteAccess(node) {
        return accessKind(node) !== 0 /* Read */;
    }
    ts.isWriteAccess = isWriteAccess;
    var AccessKind;
    (function (AccessKind) {
        /** Only reads from a variable. */
        AccessKind[AccessKind["Read"] = 0] = "Read";
        /** Only writes to a variable without using the result. E.g.: `x++;`. */
        AccessKind[AccessKind["Write"] = 1] = "Write";
        /** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
        AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite";
    })(AccessKind || (AccessKind = {}));
    function accessKind(node) {
        var parent = node.parent;
        if (!parent)
            return 0 /* Read */;
        switch (parent.kind) {
            case 193 /* PostfixUnaryExpression */:
            case 192 /* PrefixUnaryExpression */:
                var operator = parent.operator;
                return operator === 43 /* PlusPlusToken */ || operator === 44 /* MinusMinusToken */ ? writeOrReadWrite() : 0 /* Read */;
            case 194 /* BinaryExpression */:
                var _a = parent, left = _a.left, operatorToken = _a.operatorToken;
                return left === node && isAssignmentOperator(operatorToken.kind) ? writeOrReadWrite() : 0 /* Read */;
            case 179 /* PropertyAccessExpression */:
                return parent.name !== node ? 0 /* Read */ : accessKind(parent);
            default:
                return 0 /* Read */;
        }
        function writeOrReadWrite() {
            // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
            return parent.parent && parent.parent.kind === 210 /* ExpressionStatement */ ? 1 /* Write */ : 2 /* ReadWrite */;
        }
    }
    function compareDataObjects(dst, src) {
        if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
            return false;
        }
        for (var e in dst) {
            if (typeof dst[e] === "object") {
                if (!compareDataObjects(dst[e], src[e])) {
                    return false;
                }
            }
            else if (typeof dst[e] !== "function") {
                if (dst[e] !== src[e]) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.compareDataObjects = compareDataObjects;
    /**
     * clears already present map by calling onDeleteExistingValue callback before deleting that key/value
     */
    function clearMap(map, onDeleteValue) {
        // Remove all
        map.forEach(onDeleteValue);
        map.clear();
    }
    ts.clearMap = clearMap;
    /**
     * Mutates the map with newMap such that keys in map will be same as newMap.
     */
    function mutateMap(map, newMap, options) {
        var createNewValue = options.createNewValue, onDeleteValue = options.onDeleteValue, onExistingValue = options.onExistingValue;
        // Needs update
        map.forEach(function (existingValue, key) {
            var valueInNewMap = newMap.get(key);
            // Not present any more in new map, remove it
            if (valueInNewMap === undefined) {
                map.delete(key);
                onDeleteValue(existingValue, key);
            }
            else if (onExistingValue) {
                onExistingValue(existingValue, valueInNewMap, key);
            }
        });
        // Add new values that are not already present
        newMap.forEach(function (valueInNewMap, key) {
            if (!map.has(key)) {
                // New values
                map.set(key, createNewValue(key, valueInNewMap));
            }
        });
    }
    ts.mutateMap = mutateMap;
    /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
    function forEachAncestorDirectory(directory, callback) {
        while (true) {
            var result = callback(directory);
            if (result !== undefined) {
                return result;
            }
            var parentPath = ts.getDirectoryPath(directory);
            if (parentPath === directory) {
                return undefined;
            }
            directory = parentPath;
        }
    }
    ts.forEachAncestorDirectory = forEachAncestorDirectory;
})(ts || (ts = {}));
(function (ts) {
    function getDefaultLibFileName(options) {
        switch (options.target) {
            case 5 /* ESNext */:
                return "lib.esnext.full.d.ts";
            case 4 /* ES2017 */:
                return "lib.es2017.full.d.ts";
            case 3 /* ES2016 */:
                return "lib.es2016.full.d.ts";
            case 2 /* ES2015 */:
                return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change.
            default:
                return "lib.d.ts";
        }
    }
    ts.getDefaultLibFileName = getDefaultLibFileName;
    function textSpanEnd(span) {
        return span.start + span.length;
    }
    ts.textSpanEnd = textSpanEnd;
    function textSpanIsEmpty(span) {
        return span.length === 0;
    }
    ts.textSpanIsEmpty = textSpanIsEmpty;
    function textSpanContainsPosition(span, position) {
        return position >= span.start && position < textSpanEnd(span);
    }
    ts.textSpanContainsPosition = textSpanContainsPosition;
    // Returns true if 'span' contains 'other'.
    function textSpanContainsTextSpan(span, other) {
        return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
    }
    ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
    function textSpanOverlapsWith(span, other) {
        var overlapStart = Math.max(span.start, other.start);
        var overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other));
        return overlapStart < overlapEnd;
    }
    ts.textSpanOverlapsWith = textSpanOverlapsWith;
    function textSpanOverlap(span1, span2) {
        var overlapStart = Math.max(span1.start, span2.start);
        var overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
        if (overlapStart < overlapEnd) {
            return createTextSpanFromBounds(overlapStart, overlapEnd);
        }
        return undefined;
    }
    ts.textSpanOverlap = textSpanOverlap;
    function textSpanIntersectsWithTextSpan(span, other) {
        return other.start <= textSpanEnd(span) && textSpanEnd(other) >= span.start;
    }
    ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
    function textSpanIntersectsWith(span, start, length) {
        var end = start + length;
        return start <= textSpanEnd(span) && end >= span.start;
    }
    ts.textSpanIntersectsWith = textSpanIntersectsWith;
    function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
        var end1 = start1 + length1;
        var end2 = start2 + length2;
        return start2 <= end1 && end2 >= start1;
    }
    ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
    function textSpanIntersectsWithPosition(span, position) {
        return position <= textSpanEnd(span) && position >= span.start;
    }
    ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
    function textSpanIntersection(span1, span2) {
        var intersectStart = Math.max(span1.start, span2.start);
        var intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
        if (intersectStart <= intersectEnd) {
            return createTextSpanFromBounds(intersectStart, intersectEnd);
        }
        return undefined;
    }
    ts.textSpanIntersection = textSpanIntersection;
    function createTextSpan(start, length) {
        if (start < 0) {
            throw new Error("start < 0");
        }
        if (length < 0) {
            throw new Error("length < 0");
        }
        return { start: start, length: length };
    }
    ts.createTextSpan = createTextSpan;
    function createTextSpanFromBounds(start, end) {
        return createTextSpan(start, end - start);
    }
    ts.createTextSpanFromBounds = createTextSpanFromBounds;
    function textChangeRangeNewSpan(range) {
        return createTextSpan(range.span.start, range.newLength);
    }
    ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
    function textChangeRangeIsUnchanged(range) {
        return textSpanIsEmpty(range.span) && range.newLength === 0;
    }
    ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
    function createTextChangeRange(span, newLength) {
        if (newLength < 0) {
            throw new Error("newLength < 0");
        }
        return { span: span, newLength: newLength };
    }
    ts.createTextChangeRange = createTextChangeRange;
    ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0);
    /**
     * Called to merge all the changes that occurred across several versions of a script snapshot
     * into a single change.  i.e. if a user keeps making successive edits to a script we will
     * have a text change from V1 to V2, V2 to V3, ..., Vn.
     *
     * This function will then merge those changes into a single change range valid between V1 and
     * Vn.
     */
    function collapseTextChangeRangesAcrossMultipleVersions(changes) {
        if (changes.length === 0) {
            return ts.unchangedTextChangeRange;
        }
        if (changes.length === 1) {
            return changes[0];
        }
        // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
        // as it makes things much easier to reason about.
        var change0 = changes[0];
        var oldStartN = change0.span.start;
        var oldEndN = textSpanEnd(change0.span);
        var newEndN = oldStartN + change0.newLength;
        for (var i = 1; i < changes.length; i++) {
            var nextChange = changes[i];
            // Consider the following case:
            // i.e. two edits.  The first represents the text change range { { 10, 50 }, 30 }.  i.e. The span starting
            // at 10, with length 50 is reduced to length 30.  The second represents the text change range { { 30, 30 }, 40 }.
            // i.e. the span starting at 30 with length 30 is increased to length 40.
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      -------------------------------------------------------------------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      -------------------------------------------------------------------------------------------------------
            //                                     |                            \
            //                                     |                               \
            //   T2                                |                                 \
            //                                     |                                   \
            //                                     |                                      \
            //      -------------------------------------------------------------------------------------------------------
            //
            // Merging these turns out to not be too difficult.  First, determining the new start of the change is trivial
            // it's just the min of the old and new starts.  i.e.:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      ------------------------------------------------------------*------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      ----------------------------------------$-------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // (Note the dots represent the newly inferred start.
            // Determining the new and old end is also pretty simple.  Basically it boils down to paying attention to the
            // absolute positions at the asterisks, and the relative change between the dollar signs. Basically, we see
            // which if the two $'s precedes the other, and we move that one forward until they line up.  in this case that
            // means:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      --------------------------------------------------------------------------------*----------------------
            //                |                                                                     /
            //                |                                                                /----
            //  T1            |                                                           /----
            //                |                                                      /----
            //                |                                                 /----
            //      ------------------------------------------------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // In other words (in this case), we're recognizing that the second edit happened after where the first edit
            // ended with a delta of 20 characters (60 - 40).  Thus, if we go back in time to where the first edit started
            // that's the same as if we started at char 80 instead of 60.
            //
            // As it so happens, the same logic applies if the second edit precedes the first edit.  In that case rather
            // than pushing the first edit forward to match the second, we'll push the second edit forward to match the
            // first.
            //
            // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange
            // semantics: { { start: 10, length: 70 }, newLength: 60 }
            //
            // The math then works out as follows.
            // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the
            // final result like so:
            //
            // {
            //      oldStart3: Min(oldStart1, oldStart2),
            //      oldEnd3  : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
            //      newEnd3  : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
            // }
            var oldStart1 = oldStartN;
            var oldEnd1 = oldEndN;
            var newEnd1 = newEndN;
            var oldStart2 = nextChange.span.start;
            var oldEnd2 = textSpanEnd(nextChange.span);
            var newEnd2 = oldStart2 + nextChange.newLength;
            oldStartN = Math.min(oldStart1, oldStart2);
            oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
            newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
        }
        return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);
    }
    ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
    function getTypeParameterOwner(d) {
        if (d && d.kind === 145 /* TypeParameter */) {
            for (var current = d; current; current = current.parent) {
                if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 230 /* InterfaceDeclaration */) {
                    return current;
                }
            }
        }
    }
    ts.getTypeParameterOwner = getTypeParameterOwner;
    function isParameterPropertyDeclaration(node) {
        return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && node.parent.kind === 152 /* Constructor */ && ts.isClassLike(node.parent.parent);
    }
    ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration;
    function isEmptyBindingPattern(node) {
        if (ts.isBindingPattern(node)) {
            return ts.every(node.elements, isEmptyBindingElement);
        }
        return false;
    }
    ts.isEmptyBindingPattern = isEmptyBindingPattern;
    function isEmptyBindingElement(node) {
        if (ts.isOmittedExpression(node)) {
            return true;
        }
        return isEmptyBindingPattern(node.name);
    }
    ts.isEmptyBindingElement = isEmptyBindingElement;
    function walkUpBindingElementsAndPatterns(node) {
        while (node && (node.kind === 176 /* BindingElement */ || ts.isBindingPattern(node))) {
            node = node.parent;
        }
        return node;
    }
    function getCombinedModifierFlags(node) {
        node = walkUpBindingElementsAndPatterns(node);
        var flags = ts.getModifierFlags(node);
        if (node.kind === 226 /* VariableDeclaration */) {
            node = node.parent;
        }
        if (node && node.kind === 227 /* VariableDeclarationList */) {
            flags |= ts.getModifierFlags(node);
            node = node.parent;
        }
        if (node && node.kind === 208 /* VariableStatement */) {
            flags |= ts.getModifierFlags(node);
        }
        return flags;
    }
    ts.getCombinedModifierFlags = getCombinedModifierFlags;
    // Returns the node flags for this node and all relevant parent nodes.  This is done so that
    // nodes like variable declarations and binding elements can returned a view of their flags
    // that includes the modifiers from their container.  i.e. flags like export/declare aren't
    // stored on the variable declaration directly, but on the containing variable statement
    // (if it has one).  Similarly, flags for let/const are store on the variable declaration
    // list.  By calling this function, all those flags are combined so that the client can treat
    // the node as if it actually had those flags.
    function getCombinedNodeFlags(node) {
        node = walkUpBindingElementsAndPatterns(node);
        var flags = node.flags;
        if (node.kind === 226 /* VariableDeclaration */) {
            node = node.parent;
        }
        if (node && node.kind === 227 /* VariableDeclarationList */) {
            flags |= node.flags;
            node = node.parent;
        }
        if (node && node.kind === 208 /* VariableStatement */) {
            flags |= node.flags;
        }
        return flags;
    }
    ts.getCombinedNodeFlags = getCombinedNodeFlags;
    /**
     * Checks to see if the locale is in the appropriate format,
     * and if it is, attempts to set the appropriate language.
     */
    function validateLocaleAndSetLanguage(locale, sys, errors) {
        var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
        if (!matchResult) {
            if (errors) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
            }
            return;
        }
        var language = matchResult[1];
        var territory = matchResult[3];
        // First try the entire locale, then fall back to just language if that's all we have.
        // Either ways do not fail, and fallback to the English diagnostic strings.
        if (!trySetLanguageAndTerritory(language, territory, errors)) {
            trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
        }
        function trySetLanguageAndTerritory(language, territory, errors) {
            var compilerFilePath = ts.normalizePath(sys.getExecutingFilePath());
            var containingDirectoryPath = ts.getDirectoryPath(compilerFilePath);
            var filePath = ts.combinePaths(containingDirectoryPath, language);
            if (territory) {
                filePath = filePath + "-" + territory;
            }
            filePath = sys.resolvePath(ts.combinePaths(filePath, "diagnosticMessages.generated.json"));
            if (!sys.fileExists(filePath)) {
                return false;
            }
            // TODO: Add codePage support for readFile?
            var fileContents = "";
            try {
                fileContents = sys.readFile(filePath);
            }
            catch (e) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unable_to_open_file_0, filePath));
                }
                return false;
            }
            try {
                ts.localizedDiagnosticMessages = JSON.parse(fileContents);
            }
            catch (e) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Corrupted_locale_file_0, filePath));
                }
                return false;
            }
            return true;
        }
    }
    ts.validateLocaleAndSetLanguage = validateLocaleAndSetLanguage;
    function getOriginalNode(node, nodeTest) {
        if (node) {
            while (node.original !== undefined) {
                node = node.original;
            }
        }
        return !nodeTest || nodeTest(node) ? node : undefined;
    }
    ts.getOriginalNode = getOriginalNode;
    /**
     * Gets a value indicating whether a node originated in the parse tree.
     *
     * @param node The node to test.
     */
    function isParseTreeNode(node) {
        return (node.flags & 8 /* Synthesized */) === 0;
    }
    ts.isParseTreeNode = isParseTreeNode;
    function getParseTreeNode(node, nodeTest) {
        if (node === undefined || isParseTreeNode(node)) {
            return node;
        }
        node = getOriginalNode(node);
        if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
            return node;
        }
        return undefined;
    }
    ts.getParseTreeNode = getParseTreeNode;
    /**
     * Remove extra underscore from escaped identifier text content.
     *
     * @param identifier The escaped identifier text.
     * @returns The unescaped identifier text.
     */
    function unescapeLeadingUnderscores(identifier) {
        var id = identifier;
        return id.length >= 3 && id.charCodeAt(0) === 95 /* _ */ && id.charCodeAt(1) === 95 /* _ */ && id.charCodeAt(2) === 95 /* _ */ ? id.substr(1) : id;
    }
    ts.unescapeLeadingUnderscores = unescapeLeadingUnderscores;
    function idText(identifier) {
        return unescapeLeadingUnderscores(identifier.escapedText);
    }
    ts.idText = idText;
    function symbolName(symbol) {
        return unescapeLeadingUnderscores(symbol.escapedName);
    }
    ts.symbolName = symbolName;
    /**
     * Remove extra underscore from escaped identifier text content.
     * @deprecated Use `id.text` for the unescaped text.
     * @param identifier The escaped identifier text.
     * @returns The unescaped identifier text.
     */
    function unescapeIdentifier(id) {
        return id;
    }
    ts.unescapeIdentifier = unescapeIdentifier;
    /**
     * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
     * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
     * will be merged with)
     */
    function nameForNamelessJSDocTypedef(declaration) {
        var hostNode = declaration.parent.parent;
        if (!hostNode) {
            return undefined;
        }
        // Covers classes, functions - any named declaration host node
        if (ts.isDeclaration(hostNode)) {
            return getDeclarationIdentifier(hostNode);
        }
        // Covers remaining cases
        switch (hostNode.kind) {
            case 208 /* VariableStatement */:
                if (hostNode.declarationList &&
                    hostNode.declarationList.declarations[0]) {
                    return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
                }
                return undefined;
            case 210 /* ExpressionStatement */:
                var expr = hostNode.expression;
                switch (expr.kind) {
                    case 179 /* PropertyAccessExpression */:
                        return expr.name;
                    case 180 /* ElementAccessExpression */:
                        var arg = expr.argumentExpression;
                        if (ts.isIdentifier(arg)) {
                            return arg;
                        }
                }
                return undefined;
            case 1 /* EndOfFileToken */:
                return undefined;
            case 185 /* ParenthesizedExpression */: {
                return getDeclarationIdentifier(hostNode.expression);
            }
            case 222 /* LabeledStatement */: {
                if (ts.isDeclaration(hostNode.statement) || ts.isExpression(hostNode.statement)) {
                    return getDeclarationIdentifier(hostNode.statement);
                }
                return undefined;
            }
            default:
                ts.Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!");
        }
    }
    function getDeclarationIdentifier(node) {
        var name = getNameOfDeclaration(node);
        return ts.isIdentifier(name) ? name : undefined;
    }
    function getNameOfJSDocTypedef(declaration) {
        return declaration.name || nameForNamelessJSDocTypedef(declaration);
    }
    ts.getNameOfJSDocTypedef = getNameOfJSDocTypedef;
    function getNameOfDeclaration(declaration) {
        if (!declaration) {
            return undefined;
        }
        switch (declaration.kind) {
            case 284 /* JSDocPropertyTag */:
            case 279 /* JSDocParameterTag */: {
                var name = declaration.name;
                if (name.kind === 143 /* QualifiedName */) {
                    return name.right;
                }
                break;
            }
            case 194 /* BinaryExpression */: {
                var expr = declaration;
                switch (ts.getSpecialPropertyAssignmentKind(expr)) {
                    case 1 /* ExportsProperty */:
                    case 4 /* ThisProperty */:
                    case 5 /* Property */:
                    case 3 /* PrototypeProperty */:
                        return expr.left.name;
                    default:
                        return undefined;
                }
            }
            case 283 /* JSDocTypedefTag */:
                return getNameOfJSDocTypedef(declaration);
            case 243 /* ExportAssignment */: {
                var expression = declaration.expression;
                return ts.isIdentifier(expression) ? expression : undefined;
            }
        }
        return declaration.name;
    }
    ts.getNameOfDeclaration = getNameOfDeclaration;
    /**
     * Gets the JSDoc parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc param tag that matches the provided
     * parameter, whether a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the param
     * tag on the containing function expression would be first.
     *
     * Does not return tags for binding patterns, because JSDoc matches
     * parameters by name and binding patterns do not have a name.
     */
    function getJSDocParameterTags(param) {
        if (param.name && ts.isIdentifier(param.name)) {
            var name_1 = param.name.escapedText;
            return getJSDocTags(param.parent).filter(function (tag) { return ts.isJSDocParameterTag(tag) && ts.isIdentifier(tag.name) && tag.name.escapedText === name_1; });
        }
        // a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name
        return undefined;
    }
    ts.getJSDocParameterTags = getJSDocParameterTags;
    /**
     * Return true if the node has JSDoc parameter tags.
     *
     * @remarks Includes parameter tags that are not directly on the node,
     * for example on a variable declaration whose initializer is a function expression.
     */
    function hasJSDocParameterTags(node) {
        return !!getFirstJSDocTag(node, 279 /* JSDocParameterTag */);
    }
    ts.hasJSDocParameterTags = hasJSDocParameterTags;
    /** Gets the JSDoc augments tag for the node if present */
    function getJSDocAugmentsTag(node) {
        return getFirstJSDocTag(node, 277 /* JSDocAugmentsTag */);
    }
    ts.getJSDocAugmentsTag = getJSDocAugmentsTag;
    /** Gets the JSDoc class tag for the node if present */
    function getJSDocClassTag(node) {
        return getFirstJSDocTag(node, 278 /* JSDocClassTag */);
    }
    ts.getJSDocClassTag = getJSDocClassTag;
    /** Gets the JSDoc return tag for the node if present */
    function getJSDocReturnTag(node) {
        return getFirstJSDocTag(node, 280 /* JSDocReturnTag */);
    }
    ts.getJSDocReturnTag = getJSDocReturnTag;
    /** Gets the JSDoc template tag for the node if present */
    function getJSDocTemplateTag(node) {
        return getFirstJSDocTag(node, 282 /* JSDocTemplateTag */);
    }
    ts.getJSDocTemplateTag = getJSDocTemplateTag;
    /** Gets the JSDoc type tag for the node if present and valid */
    function getJSDocTypeTag(node) {
        // We should have already issued an error if there were multiple type jsdocs, so just use the first one.
        var tag = getFirstJSDocTag(node, 281 /* JSDocTypeTag */);
        if (tag && tag.typeExpression && tag.typeExpression.type) {
            return tag;
        }
        return undefined;
    }
    ts.getJSDocTypeTag = getJSDocTypeTag;
    /**
     * Gets the type node for the node if provided via JSDoc.
     *
     * @remarks The search includes any JSDoc param tag that relates
     * to the provided parameter, for example a type tag on the
     * parameter itself, or a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are examined first, so in the previous example, the type
     * tag directly on the node would be returned.
     */
    function getJSDocType(node) {
        var tag = getFirstJSDocTag(node, 281 /* JSDocTypeTag */);
        if (!tag && node.kind === 146 /* Parameter */) {
            var paramTags = getJSDocParameterTags(node);
            if (paramTags) {
                tag = ts.find(paramTags, function (tag) { return !!tag.typeExpression; });
            }
        }
        return tag && tag.typeExpression && tag.typeExpression.type;
    }
    ts.getJSDocType = getJSDocType;
    /**
     * Gets the return type node for the node if provided via JSDoc's return tag.
     *
     * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
     * gets the type from inside the braces.
     */
    function getJSDocReturnType(node) {
        var returnTag = getJSDocReturnTag(node);
        return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
    }
    ts.getJSDocReturnType = getJSDocReturnType;
    /** Get all JSDoc tags related to a node, including those on parent nodes. */
    function getJSDocTags(node) {
        var tags = node.jsDocCache;
        // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
        if (tags === undefined) {
            node.jsDocCache = tags = ts.flatMap(ts.getJSDocCommentsAndTags(node), function (j) { return ts.isJSDoc(j) ? j.tags : j; });
        }
        return tags;
    }
    ts.getJSDocTags = getJSDocTags;
    /** Get the first JSDoc tag of a specified kind, or undefined if not present. */
    function getFirstJSDocTag(node, kind) {
        var tags = getJSDocTags(node);
        return ts.find(tags, function (doc) { return doc.kind === kind; });
    }
    /** Gets all JSDoc tags of a specified kind, or undefined if not present. */
    function getAllJSDocTagsOfKind(node, kind) {
        var tags = getJSDocTags(node);
        return ts.filter(tags, function (doc) { return doc.kind === kind; });
    }
    ts.getAllJSDocTagsOfKind = getAllJSDocTagsOfKind;
})(ts || (ts = {}));
// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
(function (ts) {
    // Literals
    function isNumericLiteral(node) {
        return node.kind === 8 /* NumericLiteral */;
    }
    ts.isNumericLiteral = isNumericLiteral;
    function isStringLiteral(node) {
        return node.kind === 9 /* StringLiteral */;
    }
    ts.isStringLiteral = isStringLiteral;
    function isJsxText(node) {
        return node.kind === 10 /* JsxText */;
    }
    ts.isJsxText = isJsxText;
    function isRegularExpressionLiteral(node) {
        return node.kind === 12 /* RegularExpressionLiteral */;
    }
    ts.isRegularExpressionLiteral = isRegularExpressionLiteral;
    function isNoSubstitutionTemplateLiteral(node) {
        return node.kind === 13 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isNoSubstitutionTemplateLiteral = isNoSubstitutionTemplateLiteral;
    // Pseudo-literals
    function isTemplateHead(node) {
        return node.kind === 14 /* TemplateHead */;
    }
    ts.isTemplateHead = isTemplateHead;
    function isTemplateMiddle(node) {
        return node.kind === 15 /* TemplateMiddle */;
    }
    ts.isTemplateMiddle = isTemplateMiddle;
    function isTemplateTail(node) {
        return node.kind === 16 /* TemplateTail */;
    }
    ts.isTemplateTail = isTemplateTail;
    function isIdentifier(node) {
        return node.kind === 71 /* Identifier */;
    }
    ts.isIdentifier = isIdentifier;
    // Names
    function isQualifiedName(node) {
        return node.kind === 143 /* QualifiedName */;
    }
    ts.isQualifiedName = isQualifiedName;
    function isComputedPropertyName(node) {
        return node.kind === 144 /* ComputedPropertyName */;
    }
    ts.isComputedPropertyName = isComputedPropertyName;
    // Signature elements
    function isTypeParameterDeclaration(node) {
        return node.kind === 145 /* TypeParameter */;
    }
    ts.isTypeParameterDeclaration = isTypeParameterDeclaration;
    function isParameter(node) {
        return node.kind === 146 /* Parameter */;
    }
    ts.isParameter = isParameter;
    function isDecorator(node) {
        return node.kind === 147 /* Decorator */;
    }
    ts.isDecorator = isDecorator;
    // TypeMember
    function isPropertySignature(node) {
        return node.kind === 148 /* PropertySignature */;
    }
    ts.isPropertySignature = isPropertySignature;
    function isPropertyDeclaration(node) {
        return node.kind === 149 /* PropertyDeclaration */;
    }
    ts.isPropertyDeclaration = isPropertyDeclaration;
    function isMethodSignature(node) {
        return node.kind === 150 /* MethodSignature */;
    }
    ts.isMethodSignature = isMethodSignature;
    function isMethodDeclaration(node) {
        return node.kind === 151 /* MethodDeclaration */;
    }
    ts.isMethodDeclaration = isMethodDeclaration;
    function isConstructorDeclaration(node) {
        return node.kind === 152 /* Constructor */;
    }
    ts.isConstructorDeclaration = isConstructorDeclaration;
    function isGetAccessorDeclaration(node) {
        return node.kind === 153 /* GetAccessor */;
    }
    ts.isGetAccessorDeclaration = isGetAccessorDeclaration;
    function isSetAccessorDeclaration(node) {
        return node.kind === 154 /* SetAccessor */;
    }
    ts.isSetAccessorDeclaration = isSetAccessorDeclaration;
    function isCallSignatureDeclaration(node) {
        return node.kind === 155 /* CallSignature */;
    }
    ts.isCallSignatureDeclaration = isCallSignatureDeclaration;
    function isConstructSignatureDeclaration(node) {
        return node.kind === 156 /* ConstructSignature */;
    }
    ts.isConstructSignatureDeclaration = isConstructSignatureDeclaration;
    function isIndexSignatureDeclaration(node) {
        return node.kind === 157 /* IndexSignature */;
    }
    ts.isIndexSignatureDeclaration = isIndexSignatureDeclaration;
    // Type
    function isTypePredicateNode(node) {
        return node.kind === 158 /* TypePredicate */;
    }
    ts.isTypePredicateNode = isTypePredicateNode;
    function isTypeReferenceNode(node) {
        return node.kind === 159 /* TypeReference */;
    }
    ts.isTypeReferenceNode = isTypeReferenceNode;
    function isFunctionTypeNode(node) {
        return node.kind === 160 /* FunctionType */;
    }
    ts.isFunctionTypeNode = isFunctionTypeNode;
    function isConstructorTypeNode(node) {
        return node.kind === 161 /* ConstructorType */;
    }
    ts.isConstructorTypeNode = isConstructorTypeNode;
    function isTypeQueryNode(node) {
        return node.kind === 162 /* TypeQuery */;
    }
    ts.isTypeQueryNode = isTypeQueryNode;
    function isTypeLiteralNode(node) {
        return node.kind === 163 /* TypeLiteral */;
    }
    ts.isTypeLiteralNode = isTypeLiteralNode;
    function isArrayTypeNode(node) {
        return node.kind === 164 /* ArrayType */;
    }
    ts.isArrayTypeNode = isArrayTypeNode;
    function isTupleTypeNode(node) {
        return node.kind === 165 /* TupleType */;
    }
    ts.isTupleTypeNode = isTupleTypeNode;
    function isUnionTypeNode(node) {
        return node.kind === 166 /* UnionType */;
    }
    ts.isUnionTypeNode = isUnionTypeNode;
    function isIntersectionTypeNode(node) {
        return node.kind === 167 /* IntersectionType */;
    }
    ts.isIntersectionTypeNode = isIntersectionTypeNode;
    function isParenthesizedTypeNode(node) {
        return node.kind === 168 /* ParenthesizedType */;
    }
    ts.isParenthesizedTypeNode = isParenthesizedTypeNode;
    function isThisTypeNode(node) {
        return node.kind === 169 /* ThisType */;
    }
    ts.isThisTypeNode = isThisTypeNode;
    function isTypeOperatorNode(node) {
        return node.kind === 170 /* TypeOperator */;
    }
    ts.isTypeOperatorNode = isTypeOperatorNode;
    function isIndexedAccessTypeNode(node) {
        return node.kind === 171 /* IndexedAccessType */;
    }
    ts.isIndexedAccessTypeNode = isIndexedAccessTypeNode;
    function isMappedTypeNode(node) {
        return node.kind === 172 /* MappedType */;
    }
    ts.isMappedTypeNode = isMappedTypeNode;
    function isLiteralTypeNode(node) {
        return node.kind === 173 /* LiteralType */;
    }
    ts.isLiteralTypeNode = isLiteralTypeNode;
    // Binding patterns
    function isObjectBindingPattern(node) {
        return node.kind === 174 /* ObjectBindingPattern */;
    }
    ts.isObjectBindingPattern = isObjectBindingPattern;
    function isArrayBindingPattern(node) {
        return node.kind === 175 /* ArrayBindingPattern */;
    }
    ts.isArrayBindingPattern = isArrayBindingPattern;
    function isBindingElement(node) {
        return node.kind === 176 /* BindingElement */;
    }
    ts.isBindingElement = isBindingElement;
    // Expression
    function isArrayLiteralExpression(node) {
        return node.kind === 177 /* ArrayLiteralExpression */;
    }
    ts.isArrayLiteralExpression = isArrayLiteralExpression;
    function isObjectLiteralExpression(node) {
        return node.kind === 178 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralExpression = isObjectLiteralExpression;
    function isPropertyAccessExpression(node) {
        return node.kind === 179 /* PropertyAccessExpression */;
    }
    ts.isPropertyAccessExpression = isPropertyAccessExpression;
    function isElementAccessExpression(node) {
        return node.kind === 180 /* ElementAccessExpression */;
    }
    ts.isElementAccessExpression = isElementAccessExpression;
    function isCallExpression(node) {
        return node.kind === 181 /* CallExpression */;
    }
    ts.isCallExpression = isCallExpression;
    function isNewExpression(node) {
        return node.kind === 182 /* NewExpression */;
    }
    ts.isNewExpression = isNewExpression;
    function isTaggedTemplateExpression(node) {
        return node.kind === 183 /* TaggedTemplateExpression */;
    }
    ts.isTaggedTemplateExpression = isTaggedTemplateExpression;
    function isTypeAssertion(node) {
        return node.kind === 184 /* TypeAssertionExpression */;
    }
    ts.isTypeAssertion = isTypeAssertion;
    function isParenthesizedExpression(node) {
        return node.kind === 185 /* ParenthesizedExpression */;
    }
    ts.isParenthesizedExpression = isParenthesizedExpression;
    function skipPartiallyEmittedExpressions(node) {
        while (node.kind === 288 /* PartiallyEmittedExpression */) {
            node = node.expression;
        }
        return node;
    }
    ts.skipPartiallyEmittedExpressions = skipPartiallyEmittedExpressions;
    function isFunctionExpression(node) {
        return node.kind === 186 /* FunctionExpression */;
    }
    ts.isFunctionExpression = isFunctionExpression;
    function isArrowFunction(node) {
        return node.kind === 187 /* ArrowFunction */;
    }
    ts.isArrowFunction = isArrowFunction;
    function isDeleteExpression(node) {
        return node.kind === 188 /* DeleteExpression */;
    }
    ts.isDeleteExpression = isDeleteExpression;
    function isTypeOfExpression(node) {
        return node.kind === 191 /* AwaitExpression */;
    }
    ts.isTypeOfExpression = isTypeOfExpression;
    function isVoidExpression(node) {
        return node.kind === 190 /* VoidExpression */;
    }
    ts.isVoidExpression = isVoidExpression;
    function isAwaitExpression(node) {
        return node.kind === 191 /* AwaitExpression */;
    }
    ts.isAwaitExpression = isAwaitExpression;
    function isPrefixUnaryExpression(node) {
        return node.kind === 192 /* PrefixUnaryExpression */;
    }
    ts.isPrefixUnaryExpression = isPrefixUnaryExpression;
    function isPostfixUnaryExpression(node) {
        return node.kind === 193 /* PostfixUnaryExpression */;
    }
    ts.isPostfixUnaryExpression = isPostfixUnaryExpression;
    function isBinaryExpression(node) {
        return node.kind === 194 /* BinaryExpression */;
    }
    ts.isBinaryExpression = isBinaryExpression;
    function isConditionalExpression(node) {
        return node.kind === 195 /* ConditionalExpression */;
    }
    ts.isConditionalExpression = isConditionalExpression;
    function isTemplateExpression(node) {
        return node.kind === 196 /* TemplateExpression */;
    }
    ts.isTemplateExpression = isTemplateExpression;
    function isYieldExpression(node) {
        return node.kind === 197 /* YieldExpression */;
    }
    ts.isYieldExpression = isYieldExpression;
    function isSpreadElement(node) {
        return node.kind === 198 /* SpreadElement */;
    }
    ts.isSpreadElement = isSpreadElement;
    function isClassExpression(node) {
        return node.kind === 199 /* ClassExpression */;
    }
    ts.isClassExpression = isClassExpression;
    function isOmittedExpression(node) {
        return node.kind === 200 /* OmittedExpression */;
    }
    ts.isOmittedExpression = isOmittedExpression;
    function isExpressionWithTypeArguments(node) {
        return node.kind === 201 /* ExpressionWithTypeArguments */;
    }
    ts.isExpressionWithTypeArguments = isExpressionWithTypeArguments;
    function isAsExpression(node) {
        return node.kind === 202 /* AsExpression */;
    }
    ts.isAsExpression = isAsExpression;
    function isNonNullExpression(node) {
        return node.kind === 203 /* NonNullExpression */;
    }
    ts.isNonNullExpression = isNonNullExpression;
    function isMetaProperty(node) {
        return node.kind === 204 /* MetaProperty */;
    }
    ts.isMetaProperty = isMetaProperty;
    // Misc
    function isTemplateSpan(node) {
        return node.kind === 205 /* TemplateSpan */;
    }
    ts.isTemplateSpan = isTemplateSpan;
    function isSemicolonClassElement(node) {
        return node.kind === 206 /* SemicolonClassElement */;
    }
    ts.isSemicolonClassElement = isSemicolonClassElement;
    // Block
    function isBlock(node) {
        return node.kind === 207 /* Block */;
    }
    ts.isBlock = isBlock;
    function isVariableStatement(node) {
        return node.kind === 208 /* VariableStatement */;
    }
    ts.isVariableStatement = isVariableStatement;
    function isEmptyStatement(node) {
        return node.kind === 209 /* EmptyStatement */;
    }
    ts.isEmptyStatement = isEmptyStatement;
    function isExpressionStatement(node) {
        return node.kind === 210 /* ExpressionStatement */;
    }
    ts.isExpressionStatement = isExpressionStatement;
    function isIfStatement(node) {
        return node.kind === 211 /* IfStatement */;
    }
    ts.isIfStatement = isIfStatement;
    function isDoStatement(node) {
        return node.kind === 212 /* DoStatement */;
    }
    ts.isDoStatement = isDoStatement;
    function isWhileStatement(node) {
        return node.kind === 213 /* WhileStatement */;
    }
    ts.isWhileStatement = isWhileStatement;
    function isForStatement(node) {
        return node.kind === 214 /* ForStatement */;
    }
    ts.isForStatement = isForStatement;
    function isForInStatement(node) {
        return node.kind === 215 /* ForInStatement */;
    }
    ts.isForInStatement = isForInStatement;
    function isForOfStatement(node) {
        return node.kind === 216 /* ForOfStatement */;
    }
    ts.isForOfStatement = isForOfStatement;
    function isContinueStatement(node) {
        return node.kind === 217 /* ContinueStatement */;
    }
    ts.isContinueStatement = isContinueStatement;
    function isBreakStatement(node) {
        return node.kind === 218 /* BreakStatement */;
    }
    ts.isBreakStatement = isBreakStatement;
    function isReturnStatement(node) {
        return node.kind === 219 /* ReturnStatement */;
    }
    ts.isReturnStatement = isReturnStatement;
    function isWithStatement(node) {
        return node.kind === 220 /* WithStatement */;
    }
    ts.isWithStatement = isWithStatement;
    function isSwitchStatement(node) {
        return node.kind === 221 /* SwitchStatement */;
    }
    ts.isSwitchStatement = isSwitchStatement;
    function isLabeledStatement(node) {
        return node.kind === 222 /* LabeledStatement */;
    }
    ts.isLabeledStatement = isLabeledStatement;
    function isThrowStatement(node) {
        return node.kind === 223 /* ThrowStatement */;
    }
    ts.isThrowStatement = isThrowStatement;
    function isTryStatement(node) {
        return node.kind === 224 /* TryStatement */;
    }
    ts.isTryStatement = isTryStatement;
    function isDebuggerStatement(node) {
        return node.kind === 225 /* DebuggerStatement */;
    }
    ts.isDebuggerStatement = isDebuggerStatement;
    function isVariableDeclaration(node) {
        return node.kind === 226 /* VariableDeclaration */;
    }
    ts.isVariableDeclaration = isVariableDeclaration;
    function isVariableDeclarationList(node) {
        return node.kind === 227 /* VariableDeclarationList */;
    }
    ts.isVariableDeclarationList = isVariableDeclarationList;
    function isFunctionDeclaration(node) {
        return node.kind === 228 /* FunctionDeclaration */;
    }
    ts.isFunctionDeclaration = isFunctionDeclaration;
    function isClassDeclaration(node) {
        return node.kind === 229 /* ClassDeclaration */;
    }
    ts.isClassDeclaration = isClassDeclaration;
    function isInterfaceDeclaration(node) {
        return node.kind === 230 /* InterfaceDeclaration */;
    }
    ts.isInterfaceDeclaration = isInterfaceDeclaration;
    function isTypeAliasDeclaration(node) {
        return node.kind === 231 /* TypeAliasDeclaration */;
    }
    ts.isTypeAliasDeclaration = isTypeAliasDeclaration;
    function isEnumDeclaration(node) {
        return node.kind === 232 /* EnumDeclaration */;
    }
    ts.isEnumDeclaration = isEnumDeclaration;
    function isModuleDeclaration(node) {
        return node.kind === 233 /* ModuleDeclaration */;
    }
    ts.isModuleDeclaration = isModuleDeclaration;
    function isModuleBlock(node) {
        return node.kind === 234 /* ModuleBlock */;
    }
    ts.isModuleBlock = isModuleBlock;
    function isCaseBlock(node) {
        return node.kind === 235 /* CaseBlock */;
    }
    ts.isCaseBlock = isCaseBlock;
    function isNamespaceExportDeclaration(node) {
        return node.kind === 236 /* NamespaceExportDeclaration */;
    }
    ts.isNamespaceExportDeclaration = isNamespaceExportDeclaration;
    function isImportEqualsDeclaration(node) {
        return node.kind === 237 /* ImportEqualsDeclaration */;
    }
    ts.isImportEqualsDeclaration = isImportEqualsDeclaration;
    function isImportDeclaration(node) {
        return node.kind === 238 /* ImportDeclaration */;
    }
    ts.isImportDeclaration = isImportDeclaration;
    function isImportClause(node) {
        return node.kind === 239 /* ImportClause */;
    }
    ts.isImportClause = isImportClause;
    function isNamespaceImport(node) {
        return node.kind === 240 /* NamespaceImport */;
    }
    ts.isNamespaceImport = isNamespaceImport;
    function isNamedImports(node) {
        return node.kind === 241 /* NamedImports */;
    }
    ts.isNamedImports = isNamedImports;
    function isImportSpecifier(node) {
        return node.kind === 242 /* ImportSpecifier */;
    }
    ts.isImportSpecifier = isImportSpecifier;
    function isExportAssignment(node) {
        return node.kind === 243 /* ExportAssignment */;
    }
    ts.isExportAssignment = isExportAssignment;
    function isExportDeclaration(node) {
        return node.kind === 244 /* ExportDeclaration */;
    }
    ts.isExportDeclaration = isExportDeclaration;
    function isNamedExports(node) {
        return node.kind === 245 /* NamedExports */;
    }
    ts.isNamedExports = isNamedExports;
    function isExportSpecifier(node) {
        return node.kind === 246 /* ExportSpecifier */;
    }
    ts.isExportSpecifier = isExportSpecifier;
    function isMissingDeclaration(node) {
        return node.kind === 247 /* MissingDeclaration */;
    }
    ts.isMissingDeclaration = isMissingDeclaration;
    // Module References
    function isExternalModuleReference(node) {
        return node.kind === 248 /* ExternalModuleReference */;
    }
    ts.isExternalModuleReference = isExternalModuleReference;
    // JSX
    function isJsxElement(node) {
        return node.kind === 249 /* JsxElement */;
    }
    ts.isJsxElement = isJsxElement;
    function isJsxSelfClosingElement(node) {
        return node.kind === 250 /* JsxSelfClosingElement */;
    }
    ts.isJsxSelfClosingElement = isJsxSelfClosingElement;
    function isJsxOpeningElement(node) {
        return node.kind === 251 /* JsxOpeningElement */;
    }
    ts.isJsxOpeningElement = isJsxOpeningElement;
    function isJsxClosingElement(node) {
        return node.kind === 252 /* JsxClosingElement */;
    }
    ts.isJsxClosingElement = isJsxClosingElement;
    function isJsxAttribute(node) {
        return node.kind === 253 /* JsxAttribute */;
    }
    ts.isJsxAttribute = isJsxAttribute;
    function isJsxAttributes(node) {
        return node.kind === 254 /* JsxAttributes */;
    }
    ts.isJsxAttributes = isJsxAttributes;
    function isJsxSpreadAttribute(node) {
        return node.kind === 255 /* JsxSpreadAttribute */;
    }
    ts.isJsxSpreadAttribute = isJsxSpreadAttribute;
    function isJsxExpression(node) {
        return node.kind === 256 /* JsxExpression */;
    }
    ts.isJsxExpression = isJsxExpression;
    // Clauses
    function isCaseClause(node) {
        return node.kind === 257 /* CaseClause */;
    }
    ts.isCaseClause = isCaseClause;
    function isDefaultClause(node) {
        return node.kind === 258 /* DefaultClause */;
    }
    ts.isDefaultClause = isDefaultClause;
    function isHeritageClause(node) {
        return node.kind === 259 /* HeritageClause */;
    }
    ts.isHeritageClause = isHeritageClause;
    function isCatchClause(node) {
        return node.kind === 260 /* CatchClause */;
    }
    ts.isCatchClause = isCatchClause;
    // Property assignments
    function isPropertyAssignment(node) {
        return node.kind === 261 /* PropertyAssignment */;
    }
    ts.isPropertyAssignment = isPropertyAssignment;
    function isShorthandPropertyAssignment(node) {
        return node.kind === 262 /* ShorthandPropertyAssignment */;
    }
    ts.isShorthandPropertyAssignment = isShorthandPropertyAssignment;
    function isSpreadAssignment(node) {
        return node.kind === 263 /* SpreadAssignment */;
    }
    ts.isSpreadAssignment = isSpreadAssignment;
    // Enum
    function isEnumMember(node) {
        return node.kind === 264 /* EnumMember */;
    }
    ts.isEnumMember = isEnumMember;
    // Top-level nodes
    function isSourceFile(node) {
        return node.kind === 265 /* SourceFile */;
    }
    ts.isSourceFile = isSourceFile;
    function isBundle(node) {
        return node.kind === 266 /* Bundle */;
    }
    ts.isBundle = isBundle;
    // JSDoc
    function isJSDocTypeExpression(node) {
        return node.kind === 267 /* JSDocTypeExpression */;
    }
    ts.isJSDocTypeExpression = isJSDocTypeExpression;
    function isJSDocAllType(node) {
        return node.kind === 268 /* JSDocAllType */;
    }
    ts.isJSDocAllType = isJSDocAllType;
    function isJSDocUnknownType(node) {
        return node.kind === 269 /* JSDocUnknownType */;
    }
    ts.isJSDocUnknownType = isJSDocUnknownType;
    function isJSDocNullableType(node) {
        return node.kind === 270 /* JSDocNullableType */;
    }
    ts.isJSDocNullableType = isJSDocNullableType;
    function isJSDocNonNullableType(node) {
        return node.kind === 271 /* JSDocNonNullableType */;
    }
    ts.isJSDocNonNullableType = isJSDocNonNullableType;
    function isJSDocOptionalType(node) {
        return node.kind === 272 /* JSDocOptionalType */;
    }
    ts.isJSDocOptionalType = isJSDocOptionalType;
    function isJSDocFunctionType(node) {
        return node.kind === 273 /* JSDocFunctionType */;
    }
    ts.isJSDocFunctionType = isJSDocFunctionType;
    function isJSDocVariadicType(node) {
        return node.kind === 274 /* JSDocVariadicType */;
    }
    ts.isJSDocVariadicType = isJSDocVariadicType;
    function isJSDoc(node) {
        return node.kind === 275 /* JSDocComment */;
    }
    ts.isJSDoc = isJSDoc;
    function isJSDocAugmentsTag(node) {
        return node.kind === 277 /* JSDocAugmentsTag */;
    }
    ts.isJSDocAugmentsTag = isJSDocAugmentsTag;
    function isJSDocParameterTag(node) {
        return node.kind === 279 /* JSDocParameterTag */;
    }
    ts.isJSDocParameterTag = isJSDocParameterTag;
    function isJSDocReturnTag(node) {
        return node.kind === 280 /* JSDocReturnTag */;
    }
    ts.isJSDocReturnTag = isJSDocReturnTag;
    function isJSDocTypeTag(node) {
        return node.kind === 281 /* JSDocTypeTag */;
    }
    ts.isJSDocTypeTag = isJSDocTypeTag;
    function isJSDocTemplateTag(node) {
        return node.kind === 282 /* JSDocTemplateTag */;
    }
    ts.isJSDocTemplateTag = isJSDocTemplateTag;
    function isJSDocTypedefTag(node) {
        return node.kind === 283 /* JSDocTypedefTag */;
    }
    ts.isJSDocTypedefTag = isJSDocTypedefTag;
    function isJSDocPropertyTag(node) {
        return node.kind === 284 /* JSDocPropertyTag */;
    }
    ts.isJSDocPropertyTag = isJSDocPropertyTag;
    function isJSDocPropertyLikeTag(node) {
        return node.kind === 284 /* JSDocPropertyTag */ || node.kind === 279 /* JSDocParameterTag */;
    }
    ts.isJSDocPropertyLikeTag = isJSDocPropertyLikeTag;
    function isJSDocTypeLiteral(node) {
        return node.kind === 285 /* JSDocTypeLiteral */;
    }
    ts.isJSDocTypeLiteral = isJSDocTypeLiteral;
})(ts || (ts = {}));
// Node tests
//
// All node tests in the following list should *not* reference parent pointers so that
// they may be used with transformations.
(function (ts) {
    /* @internal */
    function isSyntaxList(n) {
        return n.kind === 286 /* SyntaxList */;
    }
    ts.isSyntaxList = isSyntaxList;
    /* @internal */
    function isNode(node) {
        return isNodeKind(node.kind);
    }
    ts.isNode = isNode;
    /* @internal */
    function isNodeKind(kind) {
        return kind >= 143 /* FirstNode */;
    }
    ts.isNodeKind = isNodeKind;
    /**
     * True if node is of some token syntax kind.
     * For example, this is true for an IfKeyword but not for an IfStatement.
     */
    function isToken(n) {
        return n.kind >= 0 /* FirstToken */ && n.kind <= 142 /* LastToken */;
    }
    ts.isToken = isToken;
    // Node Arrays
    /* @internal */
    function isNodeArray(array) {
        return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
    }
    ts.isNodeArray = isNodeArray;
    // Literals
    /* @internal */
    function isLiteralKind(kind) {
        return 8 /* FirstLiteralToken */ <= kind && kind <= 13 /* LastLiteralToken */;
    }
    ts.isLiteralKind = isLiteralKind;
    function isLiteralExpression(node) {
        return isLiteralKind(node.kind);
    }
    ts.isLiteralExpression = isLiteralExpression;
    // Pseudo-literals
    /* @internal */
    function isTemplateLiteralKind(kind) {
        return 13 /* FirstTemplateToken */ <= kind && kind <= 16 /* LastTemplateToken */;
    }
    ts.isTemplateLiteralKind = isTemplateLiteralKind;
    function isTemplateMiddleOrTemplateTail(node) {
        var kind = node.kind;
        return kind === 15 /* TemplateMiddle */
            || kind === 16 /* TemplateTail */;
    }
    ts.isTemplateMiddleOrTemplateTail = isTemplateMiddleOrTemplateTail;
    function isStringTextContainingNode(node) {
        switch (node.kind) {
            case 9 /* StringLiteral */:
            case 14 /* TemplateHead */:
            case 15 /* TemplateMiddle */:
            case 16 /* TemplateTail */:
            case 13 /* NoSubstitutionTemplateLiteral */:
                return true;
            default:
                return false;
        }
    }
    ts.isStringTextContainingNode = isStringTextContainingNode;
    // Identifiers
    /* @internal */
    function isGeneratedIdentifier(node) {
        // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
        return ts.isIdentifier(node) && node.autoGenerateKind > 0 /* None */;
    }
    ts.isGeneratedIdentifier = isGeneratedIdentifier;
    // Keywords
    /* @internal */
    function isModifierKind(token) {
        switch (token) {
            case 117 /* AbstractKeyword */:
            case 120 /* AsyncKeyword */:
            case 76 /* ConstKeyword */:
            case 124 /* DeclareKeyword */:
            case 79 /* DefaultKeyword */:
            case 84 /* ExportKeyword */:
            case 114 /* PublicKeyword */:
            case 112 /* PrivateKeyword */:
            case 113 /* ProtectedKeyword */:
            case 131 /* ReadonlyKeyword */:
            case 115 /* StaticKeyword */:
                return true;
        }
        return false;
    }
    ts.isModifierKind = isModifierKind;
    function isModifier(node) {
        return isModifierKind(node.kind);
    }
    ts.isModifier = isModifier;
    function isEntityName(node) {
        var kind = node.kind;
        return kind === 143 /* QualifiedName */
            || kind === 71 /* Identifier */;
    }
    ts.isEntityName = isEntityName;
    function isPropertyName(node) {
        var kind = node.kind;
        return kind === 71 /* Identifier */
            || kind === 9 /* StringLiteral */
            || kind === 8 /* NumericLiteral */
            || kind === 144 /* ComputedPropertyName */;
    }
    ts.isPropertyName = isPropertyName;
    function isBindingName(node) {
        var kind = node.kind;
        return kind === 71 /* Identifier */
            || kind === 174 /* ObjectBindingPattern */
            || kind === 175 /* ArrayBindingPattern */;
    }
    ts.isBindingName = isBindingName;
    // Functions
    function isFunctionLike(node) {
        return node && isFunctionLikeKind(node.kind);
    }
    ts.isFunctionLike = isFunctionLike;
    /* @internal */
    function isFunctionLikeDeclaration(node) {
        return node && isFunctionLikeDeclarationKind(node.kind);
    }
    ts.isFunctionLikeDeclaration = isFunctionLikeDeclaration;
    function isFunctionLikeDeclarationKind(kind) {
        switch (kind) {
            case 228 /* FunctionDeclaration */:
            case 151 /* MethodDeclaration */:
            case 152 /* Constructor */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 186 /* FunctionExpression */:
            case 187 /* ArrowFunction */:
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isFunctionLikeKind(kind) {
        switch (kind) {
            case 150 /* MethodSignature */:
            case 155 /* CallSignature */:
            case 156 /* ConstructSignature */:
            case 157 /* IndexSignature */:
            case 160 /* FunctionType */:
            case 273 /* JSDocFunctionType */:
            case 161 /* ConstructorType */:
                return true;
            default:
                return isFunctionLikeDeclarationKind(kind);
        }
    }
    ts.isFunctionLikeKind = isFunctionLikeKind;
    /* @internal */
    function isFunctionOrModuleBlock(node) {
        return ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isBlock(node) && isFunctionLike(node.parent);
    }
    ts.isFunctionOrModuleBlock = isFunctionOrModuleBlock;
    // Classes
    function isClassElement(node) {
        var kind = node.kind;
        return kind === 152 /* Constructor */
            || kind === 149 /* PropertyDeclaration */
            || kind === 151 /* MethodDeclaration */
            || kind === 153 /* GetAccessor */
            || kind === 154 /* SetAccessor */
            || kind === 157 /* IndexSignature */
            || kind === 206 /* SemicolonClassElement */
            || kind === 247 /* MissingDeclaration */;
    }
    ts.isClassElement = isClassElement;
    function isClassLike(node) {
        return node && (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */);
    }
    ts.isClassLike = isClassLike;
    function isAccessor(node) {
        return node && (node.kind === 153 /* GetAccessor */ || node.kind === 154 /* SetAccessor */);
    }
    ts.isAccessor = isAccessor;
    // Type members
    function isTypeElement(node) {
        var kind = node.kind;
        return kind === 156 /* ConstructSignature */
            || kind === 155 /* CallSignature */
            || kind === 148 /* PropertySignature */
            || kind === 150 /* MethodSignature */
            || kind === 157 /* IndexSignature */
            || kind === 247 /* MissingDeclaration */;
    }
    ts.isTypeElement = isTypeElement;
    function isObjectLiteralElementLike(node) {
        var kind = node.kind;
        return kind === 261 /* PropertyAssignment */
            || kind === 262 /* ShorthandPropertyAssignment */
            || kind === 263 /* SpreadAssignment */
            || kind === 151 /* MethodDeclaration */
            || kind === 153 /* GetAccessor */
            || kind === 154 /* SetAccessor */
            || kind === 247 /* MissingDeclaration */;
    }
    ts.isObjectLiteralElementLike = isObjectLiteralElementLike;
    // Type
    function isTypeNodeKind(kind) {
        return (kind >= 158 /* FirstTypeNode */ && kind <= 173 /* LastTypeNode */)
            || kind === 119 /* AnyKeyword */
            || kind === 133 /* NumberKeyword */
            || kind === 134 /* ObjectKeyword */
            || kind === 122 /* BooleanKeyword */
            || kind === 136 /* StringKeyword */
            || kind === 137 /* SymbolKeyword */
            || kind === 99 /* ThisKeyword */
            || kind === 105 /* VoidKeyword */
            || kind === 139 /* UndefinedKeyword */
            || kind === 95 /* NullKeyword */
            || kind === 130 /* NeverKeyword */
            || kind === 201 /* ExpressionWithTypeArguments */
            || kind === 268 /* JSDocAllType */
            || kind === 269 /* JSDocUnknownType */
            || kind === 270 /* JSDocNullableType */
            || kind === 271 /* JSDocNonNullableType */
            || kind === 272 /* JSDocOptionalType */
            || kind === 273 /* JSDocFunctionType */
            || kind === 274 /* JSDocVariadicType */;
    }
    /**
     * Node test that determines whether a node is a valid type node.
     * This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
     * of a TypeNode.
     */
    function isTypeNode(node) {
        return isTypeNodeKind(node.kind);
    }
    ts.isTypeNode = isTypeNode;
    function isFunctionOrConstructorTypeNode(node) {
        switch (node.kind) {
            case 160 /* FunctionType */:
            case 161 /* ConstructorType */:
                return true;
        }
        return false;
    }
    ts.isFunctionOrConstructorTypeNode = isFunctionOrConstructorTypeNode;
    // Binding patterns
    /* @internal */
    function isBindingPattern(node) {
        if (node) {
            var kind = node.kind;
            return kind === 175 /* ArrayBindingPattern */
                || kind === 174 /* ObjectBindingPattern */;
        }
        return false;
    }
    ts.isBindingPattern = isBindingPattern;
    /* @internal */
    function isAssignmentPattern(node) {
        var kind = node.kind;
        return kind === 177 /* ArrayLiteralExpression */
            || kind === 178 /* ObjectLiteralExpression */;
    }
    ts.isAssignmentPattern = isAssignmentPattern;
    /* @internal */
    function isArrayBindingElement(node) {
        var kind = node.kind;
        return kind === 176 /* BindingElement */
            || kind === 200 /* OmittedExpression */;
    }
    ts.isArrayBindingElement = isArrayBindingElement;
    /**
     * Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration
     */
    /* @internal */
    function isDeclarationBindingElement(bindingElement) {
        switch (bindingElement.kind) {
            case 226 /* VariableDeclaration */:
            case 146 /* Parameter */:
            case 176 /* BindingElement */:
                return true;
        }
        return false;
    }
    ts.isDeclarationBindingElement = isDeclarationBindingElement;
    /**
     * Determines whether a node is a BindingOrAssignmentPattern
     */
    /* @internal */
    function isBindingOrAssignmentPattern(node) {
        return isObjectBindingOrAssignmentPattern(node)
            || isArrayBindingOrAssignmentPattern(node);
    }
    ts.isBindingOrAssignmentPattern = isBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ObjectBindingOrAssignmentPattern
     */
    /* @internal */
    function isObjectBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 174 /* ObjectBindingPattern */:
            case 178 /* ObjectLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isObjectBindingOrAssignmentPattern = isObjectBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ArrayBindingOrAssignmentPattern
     */
    /* @internal */
    function isArrayBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 175 /* ArrayBindingPattern */:
            case 177 /* ArrayLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isArrayBindingOrAssignmentPattern = isArrayBindingOrAssignmentPattern;
    // Expression
    function isPropertyAccessOrQualifiedName(node) {
        var kind = node.kind;
        return kind === 179 /* PropertyAccessExpression */
            || kind === 143 /* QualifiedName */;
    }
    ts.isPropertyAccessOrQualifiedName = isPropertyAccessOrQualifiedName;
    function isCallLikeExpression(node) {
        switch (node.kind) {
            case 251 /* JsxOpeningElement */:
            case 250 /* JsxSelfClosingElement */:
            case 181 /* CallExpression */:
            case 182 /* NewExpression */:
            case 183 /* TaggedTemplateExpression */:
            case 147 /* Decorator */:
                return true;
            default:
                return false;
        }
    }
    ts.isCallLikeExpression = isCallLikeExpression;
    function isCallOrNewExpression(node) {
        return node.kind === 181 /* CallExpression */ || node.kind === 182 /* NewExpression */;
    }
    ts.isCallOrNewExpression = isCallOrNewExpression;
    function isTemplateLiteral(node) {
        var kind = node.kind;
        return kind === 196 /* TemplateExpression */
            || kind === 13 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isTemplateLiteral = isTemplateLiteral;
    /* @internal */
    function isLeftHandSideExpression(node) {
        return isLeftHandSideExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isLeftHandSideExpression = isLeftHandSideExpression;
    function isLeftHandSideExpressionKind(kind) {
        switch (kind) {
            case 179 /* PropertyAccessExpression */:
            case 180 /* ElementAccessExpression */:
            case 182 /* NewExpression */:
            case 181 /* CallExpression */:
            case 249 /* JsxElement */:
            case 250 /* JsxSelfClosingElement */:
            case 183 /* TaggedTemplateExpression */:
            case 177 /* ArrayLiteralExpression */:
            case 185 /* ParenthesizedExpression */:
            case 178 /* ObjectLiteralExpression */:
            case 199 /* ClassExpression */:
            case 186 /* FunctionExpression */:
            case 71 /* Identifier */:
            case 12 /* RegularExpressionLiteral */:
            case 8 /* NumericLiteral */:
            case 9 /* StringLiteral */:
            case 13 /* NoSubstitutionTemplateLiteral */:
            case 196 /* TemplateExpression */:
            case 86 /* FalseKeyword */:
            case 95 /* NullKeyword */:
            case 99 /* ThisKeyword */:
            case 101 /* TrueKeyword */:
            case 97 /* SuperKeyword */:
            case 203 /* NonNullExpression */:
            case 204 /* MetaProperty */:
            case 91 /* ImportKeyword */:// technically this is only an Expression if it's in a CallExpression
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isUnaryExpression(node) {
        return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isUnaryExpression = isUnaryExpression;
    function isUnaryExpressionKind(kind) {
        switch (kind) {
            case 192 /* PrefixUnaryExpression */:
            case 193 /* PostfixUnaryExpression */:
            case 188 /* DeleteExpression */:
            case 189 /* TypeOfExpression */:
            case 190 /* VoidExpression */:
            case 191 /* AwaitExpression */:
            case 184 /* TypeAssertionExpression */:
                return true;
            default:
                return isLeftHandSideExpressionKind(kind);
        }
    }
    /* @internal */
    function isUnaryExpressionWithWrite(expr) {
        switch (expr.kind) {
            case 193 /* PostfixUnaryExpression */:
                return true;
            case 192 /* PrefixUnaryExpression */:
                return expr.operator === 43 /* PlusPlusToken */ ||
                    expr.operator === 44 /* MinusMinusToken */;
            default:
                return false;
        }
    }
    ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite;
    /* @internal */
    /**
     * Determines whether a node is an expression based only on its kind.
     * Use `isPartOfExpression` if not in transforms.
     */
    function isExpression(node) {
        return isExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isExpression = isExpression;
    function isExpressionKind(kind) {
        switch (kind) {
            case 195 /* ConditionalExpression */:
            case 197 /* YieldExpression */:
            case 187 /* ArrowFunction */:
            case 194 /* BinaryExpression */:
            case 198 /* SpreadElement */:
            case 202 /* AsExpression */:
            case 200 /* OmittedExpression */:
            case 289 /* CommaListExpression */:
            case 288 /* PartiallyEmittedExpression */:
                return true;
            default:
                return isUnaryExpressionKind(kind);
        }
    }
    function isAssertionExpression(node) {
        var kind = node.kind;
        return kind === 184 /* TypeAssertionExpression */
            || kind === 202 /* AsExpression */;
    }
    ts.isAssertionExpression = isAssertionExpression;
    /* @internal */
    function isPartiallyEmittedExpression(node) {
        return node.kind === 288 /* PartiallyEmittedExpression */;
    }
    ts.isPartiallyEmittedExpression = isPartiallyEmittedExpression;
    /* @internal */
    function isNotEmittedStatement(node) {
        return node.kind === 287 /* NotEmittedStatement */;
    }
    ts.isNotEmittedStatement = isNotEmittedStatement;
    /* @internal */
    function isNotEmittedOrPartiallyEmittedNode(node) {
        return isNotEmittedStatement(node)
            || isPartiallyEmittedExpression(node);
    }
    ts.isNotEmittedOrPartiallyEmittedNode = isNotEmittedOrPartiallyEmittedNode;
    // Statement
    function isIterationStatement(node, lookInLabeledStatements) {
        switch (node.kind) {
            case 214 /* ForStatement */:
            case 215 /* ForInStatement */:
            case 216 /* ForOfStatement */:
            case 212 /* DoStatement */:
            case 213 /* WhileStatement */:
                return true;
            case 222 /* LabeledStatement */:
                return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
        }
        return false;
    }
    ts.isIterationStatement = isIterationStatement;
    /* @internal */
    function isForInOrOfStatement(node) {
        return node.kind === 215 /* ForInStatement */ || node.kind === 216 /* ForOfStatement */;
    }
    ts.isForInOrOfStatement = isForInOrOfStatement;
    // Element
    /* @internal */
    function isConciseBody(node) {
        return ts.isBlock(node)
            || isExpression(node);
    }
    ts.isConciseBody = isConciseBody;
    /* @internal */
    function isFunctionBody(node) {
        return ts.isBlock(node);
    }
    ts.isFunctionBody = isFunctionBody;
    /* @internal */
    function isForInitializer(node) {
        return ts.isVariableDeclarationList(node)
            || isExpression(node);
    }
    ts.isForInitializer = isForInitializer;
    /* @internal */
    function isModuleBody(node) {
        var kind = node.kind;
        return kind === 234 /* ModuleBlock */
            || kind === 233 /* ModuleDeclaration */
            || kind === 71 /* Identifier */;
    }
    ts.isModuleBody = isModuleBody;
    /* @internal */
    function isNamespaceBody(node) {
        var kind = node.kind;
        return kind === 234 /* ModuleBlock */
            || kind === 233 /* ModuleDeclaration */;
    }
    ts.isNamespaceBody = isNamespaceBody;
    /* @internal */
    function isJSDocNamespaceBody(node) {
        var kind = node.kind;
        return kind === 71 /* Identifier */
            || kind === 233 /* ModuleDeclaration */;
    }
    ts.isJSDocNamespaceBody = isJSDocNamespaceBody;
    /* @internal */
    function isNamedImportBindings(node) {
        var kind = node.kind;
        return kind === 241 /* NamedImports */
            || kind === 240 /* NamespaceImport */;
    }
    ts.isNamedImportBindings = isNamedImportBindings;
    /* @internal */
    function isModuleOrEnumDeclaration(node) {
        return node.kind === 233 /* ModuleDeclaration */ || node.kind === 232 /* EnumDeclaration */;
    }
    ts.isModuleOrEnumDeclaration = isModuleOrEnumDeclaration;
    function isDeclarationKind(kind) {
        return kind === 187 /* ArrowFunction */
            || kind === 176 /* BindingElement */
            || kind === 229 /* ClassDeclaration */
            || kind === 199 /* ClassExpression */
            || kind === 152 /* Constructor */
            || kind === 232 /* EnumDeclaration */
            || kind === 264 /* EnumMember */
            || kind === 246 /* ExportSpecifier */
            || kind === 228 /* FunctionDeclaration */
            || kind === 186 /* FunctionExpression */
            || kind === 153 /* GetAccessor */
            || kind === 239 /* ImportClause */
            || kind === 237 /* ImportEqualsDeclaration */
            || kind === 242 /* ImportSpecifier */
            || kind === 230 /* InterfaceDeclaration */
            || kind === 253 /* JsxAttribute */
            || kind === 151 /* MethodDeclaration */
            || kind === 150 /* MethodSignature */
            || kind === 233 /* ModuleDeclaration */
            || kind === 236 /* NamespaceExportDeclaration */
            || kind === 240 /* NamespaceImport */
            || kind === 146 /* Parameter */
            || kind === 261 /* PropertyAssignment */
            || kind === 149 /* PropertyDeclaration */
            || kind === 148 /* PropertySignature */
            || kind === 154 /* SetAccessor */
            || kind === 262 /* ShorthandPropertyAssignment */
            || kind === 231 /* TypeAliasDeclaration */
            || kind === 145 /* TypeParameter */
            || kind === 226 /* VariableDeclaration */
            || kind === 283 /* JSDocTypedefTag */;
    }
    function isDeclarationStatementKind(kind) {
        return kind === 228 /* FunctionDeclaration */
            || kind === 247 /* MissingDeclaration */
            || kind === 229 /* ClassDeclaration */
            || kind === 230 /* InterfaceDeclaration */
            || kind === 231 /* TypeAliasDeclaration */
            || kind === 232 /* EnumDeclaration */
            || kind === 233 /* ModuleDeclaration */
            || kind === 238 /* ImportDeclaration */
            || kind === 237 /* ImportEqualsDeclaration */
            || kind === 244 /* ExportDeclaration */
            || kind === 243 /* ExportAssignment */
            || kind === 236 /* NamespaceExportDeclaration */;
    }
    function isStatementKindButNotDeclarationKind(kind) {
        return kind === 218 /* BreakStatement */
            || kind === 217 /* ContinueStatement */
            || kind === 225 /* DebuggerStatement */
            || kind === 212 /* DoStatement */
            || kind === 210 /* ExpressionStatement */
            || kind === 209 /* EmptyStatement */
            || kind === 215 /* ForInStatement */
            || kind === 216 /* ForOfStatement */
            || kind === 214 /* ForStatement */
            || kind === 211 /* IfStatement */
            || kind === 222 /* LabeledStatement */
            || kind === 219 /* ReturnStatement */
            || kind === 221 /* SwitchStatement */
            || kind === 223 /* ThrowStatement */
            || kind === 224 /* TryStatement */
            || kind === 208 /* VariableStatement */
            || kind === 213 /* WhileStatement */
            || kind === 220 /* WithStatement */
            || kind === 287 /* NotEmittedStatement */
            || kind === 291 /* EndOfDeclarationMarker */
            || kind === 290 /* MergeDeclarationMarker */;
    }
    /* @internal */
    function isDeclaration(node) {
        if (node.kind === 145 /* TypeParameter */) {
            return node.parent.kind !== 282 /* JSDocTemplateTag */ || ts.isInJavaScriptFile(node);
        }
        return isDeclarationKind(node.kind);
    }
    ts.isDeclaration = isDeclaration;
    /* @internal */
    function isDeclarationStatement(node) {
        return isDeclarationStatementKind(node.kind);
    }
    ts.isDeclarationStatement = isDeclarationStatement;
    /**
     * Determines whether the node is a statement that is not also a declaration
     */
    /* @internal */
    function isStatementButNotDeclaration(node) {
        return isStatementKindButNotDeclarationKind(node.kind);
    }
    ts.isStatementButNotDeclaration = isStatementButNotDeclaration;
    /* @internal */
    function isStatement(node) {
        var kind = node.kind;
        return isStatementKindButNotDeclarationKind(kind)
            || isDeclarationStatementKind(kind)
            || isBlockStatement(node);
    }
    ts.isStatement = isStatement;
    function isBlockStatement(node) {
        if (node.kind !== 207 /* Block */)
            return false;
        if (node.parent !== undefined) {
            if (node.parent.kind === 224 /* TryStatement */ || node.parent.kind === 260 /* CatchClause */) {
                return false;
            }
        }
        return !ts.isFunctionBlock(node);
    }
    // Module references
    /* @internal */
    function isModuleReference(node) {
        var kind = node.kind;
        return kind === 248 /* ExternalModuleReference */
            || kind === 143 /* QualifiedName */
            || kind === 71 /* Identifier */;
    }
    ts.isModuleReference = isModuleReference;
    // JSX
    /* @internal */
    function isJsxTagNameExpression(node) {
        var kind = node.kind;
        return kind === 99 /* ThisKeyword */
            || kind === 71 /* Identifier */
            || kind === 179 /* PropertyAccessExpression */;
    }
    ts.isJsxTagNameExpression = isJsxTagNameExpression;
    /* @internal */
    function isJsxChild(node) {
        var kind = node.kind;
        return kind === 249 /* JsxElement */
            || kind === 256 /* JsxExpression */
            || kind === 250 /* JsxSelfClosingElement */
            || kind === 10 /* JsxText */;
    }
    ts.isJsxChild = isJsxChild;
    /* @internal */
    function isJsxAttributeLike(node) {
        var kind = node.kind;
        return kind === 253 /* JsxAttribute */
            || kind === 255 /* JsxSpreadAttribute */;
    }
    ts.isJsxAttributeLike = isJsxAttributeLike;
    /* @internal */
    function isStringLiteralOrJsxExpression(node) {
        var kind = node.kind;
        return kind === 9 /* StringLiteral */
            || kind === 256 /* JsxExpression */;
    }
    ts.isStringLiteralOrJsxExpression = isStringLiteralOrJsxExpression;
    function isJsxOpeningLikeElement(node) {
        var kind = node.kind;
        return kind === 251 /* JsxOpeningElement */
            || kind === 250 /* JsxSelfClosingElement */;
    }
    ts.isJsxOpeningLikeElement = isJsxOpeningLikeElement;
    // Clauses
    function isCaseOrDefaultClause(node) {
        var kind = node.kind;
        return kind === 257 /* CaseClause */
            || kind === 258 /* DefaultClause */;
    }
    ts.isCaseOrDefaultClause = isCaseOrDefaultClause;
    // JSDoc
    /** True if node is of some JSDoc syntax kind. */
    /* @internal */
    function isJSDocNode(node) {
        return node.kind >= 267 /* FirstJSDocNode */ && node.kind <= 285 /* LastJSDocNode */;
    }
    ts.isJSDocNode = isJSDocNode;
    /** True if node is of a kind that may contain comment text. */
    function isJSDocCommentContainingNode(node) {
        return node.kind === 275 /* JSDocComment */ || isJSDocTag(node);
    }
    ts.isJSDocCommentContainingNode = isJSDocCommentContainingNode;
    // TODO: determine what this does before making it public.
    /* @internal */
    function isJSDocTag(node) {
        return node.kind >= 276 /* FirstJSDocTagNode */ && node.kind <= 285 /* LastJSDocTagNode */;
    }
    ts.isJSDocTag = isJSDocTag;
    function isSetAccessor(node) {
        return node.kind === 154 /* SetAccessor */;
    }
    ts.isSetAccessor = isSetAccessor;
    function isGetAccessor(node) {
        return node.kind === 153 /* GetAccessor */;
    }
    ts.isGetAccessor = isGetAccessor;
    /** True if has jsdoc nodes attached to it. */
    /* @internal */
    function hasJSDocNodes(node) {
        return !!node.jsDoc && node.jsDoc.length > 0;
    }
    ts.hasJSDocNodes = hasJSDocNodes;
})(ts || (ts = {}));
/// <reference path="utilities.ts"/>
/// <reference path="scanner.ts"/>
var ts;
(function (ts) {
    var SignatureFlags;
    (function (SignatureFlags) {
        SignatureFlags[SignatureFlags["None"] = 0] = "None";
        SignatureFlags[SignatureFlags["Yield"] = 1] = "Yield";
        SignatureFlags[SignatureFlags["Await"] = 2] = "Await";
        SignatureFlags[SignatureFlags["Type"] = 4] = "Type";
        SignatureFlags[SignatureFlags["RequireCompleteParameterList"] = 8] = "RequireCompleteParameterList";
        SignatureFlags[SignatureFlags["IgnoreMissingOpenBrace"] = 16] = "IgnoreMissingOpenBrace";
        SignatureFlags[SignatureFlags["JSDoc"] = 32] = "JSDoc";
    })(SignatureFlags || (SignatureFlags = {}));
    var NodeConstructor;
    var TokenConstructor;
    var IdentifierConstructor;
    var SourceFileConstructor;
    function createNode(kind, pos, end) {
        if (kind === 265 /* SourceFile */) {
            return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
        }
        else if (kind === 71 /* Identifier */) {
            return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end);
        }
        else if (!ts.isNodeKind(kind)) {
            return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end);
        }
        else {
            return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
        }
    }
    ts.createNode = createNode;
    function visitNode(cbNode, node) {
        return node && cbNode(node);
    }
    function visitNodes(cbNode, cbNodes, nodes) {
        if (nodes) {
            if (cbNodes) {
                return cbNodes(nodes);
            }
            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
                var node = nodes_1[_i];
                var result = cbNode(node);
                if (result) {
                    return result;
                }
            }
        }
    }
    /**
     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
     * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
     * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
     *
     * @param node a given node to visit its children
     * @param cbNode a callback to be invoked for all child nodes
     * @param cbNodes a callback to be invoked for embedded array
     *
     * @remarks `forEachChild` must visit the children of a node in the order
     * that they appear in the source code. The language service depends on this property to locate nodes by position.
     */
    function forEachChild(node, cbNode, cbNodes) {
        if (!node || node.kind <= 142 /* LastToken */) {
            return;
        }
        switch (node.kind) {
            case 143 /* QualifiedName */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.right);
            case 145 /* TypeParameter */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNode(cbNode, node.default) ||
                    visitNode(cbNode, node.expression);
            case 262 /* ShorthandPropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.equalsToken) ||
                    visitNode(cbNode, node.objectAssignmentInitializer);
            case 263 /* SpreadAssignment */:
                return visitNode(cbNode, node.expression);
            case 146 /* Parameter */:
            case 149 /* PropertyDeclaration */:
            case 148 /* PropertySignature */:
            case 261 /* PropertyAssignment */:
            case 226 /* VariableDeclaration */:
            case 176 /* BindingElement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 160 /* FunctionType */:
            case 161 /* ConstructorType */:
            case 155 /* CallSignature */:
            case 156 /* ConstructSignature */:
            case 157 /* IndexSignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
            case 152 /* Constructor */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 186 /* FunctionExpression */:
            case 228 /* FunctionDeclaration */:
            case 187 /* ArrowFunction */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.equalsGreaterThanToken) ||
                    visitNode(cbNode, node.body);
            case 159 /* TypeReference */:
                return visitNode(cbNode, node.typeName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 158 /* TypePredicate */:
                return visitNode(cbNode, node.parameterName) ||
                    visitNode(cbNode, node.type);
            case 162 /* TypeQuery */:
                return visitNode(cbNode, node.exprName);
            case 163 /* TypeLiteral */:
                return visitNodes(cbNode, cbNodes, node.members);
            case 164 /* ArrayType */:
                return visitNode(cbNode, node.elementType);
            case 165 /* TupleType */:
                return visitNodes(cbNode, cbNodes, node.elementTypes);
            case 166 /* UnionType */:
            case 167 /* IntersectionType */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 168 /* ParenthesizedType */:
            case 170 /* TypeOperator */:
                return visitNode(cbNode, node.type);
            case 171 /* IndexedAccessType */:
                return visitNode(cbNode, node.objectType) ||
                    visitNode(cbNode, node.indexType);
            case 172 /* MappedType */:
                return visitNode(cbNode, node.readonlyToken) ||
                    visitNode(cbNode, node.typeParameter) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type);
            case 173 /* LiteralType */:
                return visitNode(cbNode, node.literal);
            case 174 /* ObjectBindingPattern */:
            case 175 /* ArrayBindingPattern */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 177 /* ArrayLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 178 /* ObjectLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 179 /* PropertyAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.name);
            case 180 /* ElementAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.argumentExpression);
            case 181 /* CallExpression */:
            case 182 /* NewExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNodes(cbNode, cbNodes, node.arguments);
            case 183 /* TaggedTemplateExpression */:
                return visitNode(cbNode, node.tag) ||
                    visitNode(cbNode, node.template);
            case 184 /* TypeAssertionExpression */:
                return visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.expression);
            case 185 /* ParenthesizedExpression */:
                return visitNode(cbNode, node.expression);
            case 188 /* DeleteExpression */:
                return visitNode(cbNode, node.expression);
            case 189 /* TypeOfExpression */:
                return visitNode(cbNode, node.expression);
            case 190 /* VoidExpression */:
                return visitNode(cbNode, node.expression);
            case 192 /* PrefixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 197 /* YieldExpression */:
                return visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.expression);
            case 191 /* AwaitExpression */:
                return visitNode(cbNode, node.expression);
            case 193 /* PostfixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 194 /* BinaryExpression */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.operatorToken) ||
                    visitNode(cbNode, node.right);
            case 202 /* AsExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.type);
            case 203 /* NonNullExpression */:
                return visitNode(cbNode, node.expression);
            case 204 /* MetaProperty */:
                return visitNode(cbNode, node.name);
            case 195 /* ConditionalExpression */:
                return visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.whenTrue) ||
                    visitNode(cbNode, node.colonToken) ||
                    visitNode(cbNode, node.whenFalse);
            case 198 /* SpreadElement */:
                return visitNode(cbNode, node.expression);
            case 207 /* Block */:
            case 234 /* ModuleBlock */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 265 /* SourceFile */:
                return visitNodes(cbNode, cbNodes, node.statements) ||
                    visitNode(cbNode, node.endOfFileToken);
            case 208 /* VariableStatement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.declarationList);
            case 227 /* VariableDeclarationList */:
                return visitNodes(cbNode, cbNodes, node.declarations);
            case 210 /* ExpressionStatement */:
                return visitNode(cbNode, node.expression);
            case 211 /* IfStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.thenStatement) ||
                    visitNode(cbNode, node.elseStatement);
            case 212 /* DoStatement */:
                return visitNode(cbNode, node.statement) ||
                    visitNode(cbNode, node.expression);
            case 213 /* WhileStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 214 /* ForStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.incrementor) ||
                    visitNode(cbNode, node.statement);
            case 215 /* ForInStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 216 /* ForOfStatement */:
                return visitNode(cbNode, node.awaitModifier) ||
                    visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 217 /* ContinueStatement */:
            case 218 /* BreakStatement */:
                return visitNode(cbNode, node.label);
            case 219 /* ReturnStatement */:
                return visitNode(cbNode, node.expression);
            case 220 /* WithStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 221 /* SwitchStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.caseBlock);
            case 235 /* CaseBlock */:
                return visitNodes(cbNode, cbNodes, node.clauses);
            case 257 /* CaseClause */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.statements);
            case 258 /* DefaultClause */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 222 /* LabeledStatement */:
                return visitNode(cbNode, node.label) ||
                    visitNode(cbNode, node.statement);
            case 223 /* ThrowStatement */:
                return visitNode(cbNode, node.expression);
            case 224 /* TryStatement */:
                return visitNode(cbNode, node.tryBlock) ||
                    visitNode(cbNode, node.catchClause) ||
                    visitNode(cbNode, node.finallyBlock);
            case 260 /* CatchClause */:
                return visitNode(cbNode, node.variableDeclaration) ||
                    visitNode(cbNode, node.block);
            case 147 /* Decorator */:
                return visitNode(cbNode, node.expression);
            case 229 /* ClassDeclaration */:
            case 199 /* ClassExpression */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 230 /* InterfaceDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 231 /* TypeAliasDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNode(cbNode, node.type);
            case 232 /* EnumDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 264 /* EnumMember */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 233 /* ModuleDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.body);
            case 237 /* ImportEqualsDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.moduleReference);
            case 238 /* ImportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.importClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 239 /* ImportClause */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.namedBindings);
            case 236 /* NamespaceExportDeclaration */:
                return visitNode(cbNode, node.name);
            case 240 /* NamespaceImport */:
                return visitNode(cbNode, node.name);
            case 241 /* NamedImports */:
            case 245 /* NamedExports */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 244 /* ExportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.exportClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 242 /* ImportSpecifier */:
            case 246 /* ExportSpecifier */:
                return visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name);
            case 243 /* ExportAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.expression);
            case 196 /* TemplateExpression */:
                return visitNode(cbNode, node.head) || visitNodes(cbNode, cbNodes, node.templateSpans);
            case 205 /* TemplateSpan */:
                return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal);
            case 144 /* ComputedPropertyName */:
                return visitNode(cbNode, node.expression);
            case 259 /* HeritageClause */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 201 /* ExpressionWithTypeArguments */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 248 /* ExternalModuleReference */:
                return visitNode(cbNode, node.expression);
            case 247 /* MissingDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators);
            case 289 /* CommaListExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 249 /* JsxElement */:
                return visitNode(cbNode, node.openingElement) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingElement);
            case 250 /* JsxSelfClosingElement */:
            case 251 /* JsxOpeningElement */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.attributes);
            case 254 /* JsxAttributes */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 253 /* JsxAttribute */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 255 /* JsxSpreadAttribute */:
                return visitNode(cbNode, node.expression);
            case 256 /* JsxExpression */:
                return visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.expression);
            case 252 /* JsxClosingElement */:
                return visitNode(cbNode, node.tagName);
            case 267 /* JSDocTypeExpression */:
                return visitNode(cbNode, node.type);
            case 271 /* JSDocNonNullableType */:
                return visitNode(cbNode, node.type);
            case 270 /* JSDocNullableType */:
                return visitNode(cbNode, node.type);
            case 272 /* JSDocOptionalType */:
                return visitNode(cbNode, node.type);
            case 273 /* JSDocFunctionType */:
                return visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 274 /* JSDocVariadicType */:
                return visitNode(cbNode, node.type);
            case 275 /* JSDocComment */:
                return visitNodes(cbNode, cbNodes, node.tags);
            case 279 /* JSDocParameterTag */:
            case 284 /* JSDocPropertyTag */:
                if (node.isNameFirst) {
                    return visitNode(cbNode, node.name) ||
                        visitNode(cbNode, node.typeExpression);
                }
                else {
                    return visitNode(cbNode, node.typeExpression) ||
                        visitNode(cbNode, node.name);
                }
            case 280 /* JSDocReturnTag */:
                return visitNode(cbNode, node.typeExpression);
            case 281 /* JSDocTypeTag */:
                return visitNode(cbNode, node.typeExpression);
            case 277 /* JSDocAugmentsTag */:
                return visitNode(cbNode, node.class);
            case 282 /* JSDocTemplateTag */:
                return visitNodes(cbNode, cbNodes, node.typeParameters);
            case 283 /* JSDocTypedefTag */:
                if (node.typeExpression &&
                    node.typeExpression.kind === 267 /* JSDocTypeExpression */) {
                    return visitNode(cbNode, node.typeExpression) ||
                        visitNode(cbNode, node.fullName);
                }
                else {
                    return visitNode(cbNode, node.fullName) ||
                        visitNode(cbNode, node.typeExpression);
                }
            case 285 /* JSDocTypeLiteral */:
                if (node.jsDocPropertyTags) {
                    for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) {
                        var tag = _a[_i];
                        visitNode(cbNode, tag);
                    }
                }
                return;
            case 288 /* PartiallyEmittedExpression */:
                return visitNode(cbNode, node.expression);
        }
    }
    ts.forEachChild = forEachChild;
    function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) {
        if (setParentNodes === void 0) { setParentNodes = false; }
        ts.performance.mark("beforeParse");
        var result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
        ts.performance.mark("afterParse");
        ts.performance.measure("Parse", "beforeParse", "afterParse");
        return result;
    }
    ts.createSourceFile = createSourceFile;
    function parseIsolatedEntityName(text, languageVersion) {
        return Parser.parseIsolatedEntityName(text, languageVersion);
    }
    ts.parseIsolatedEntityName = parseIsolatedEntityName;
    /**
     * Parse json text into SyntaxTree and return node and parse errors if any
     * @param fileName
     * @param sourceText
     */
    function parseJsonText(fileName, sourceText) {
        return Parser.parseJsonText(fileName, sourceText);
    }
    ts.parseJsonText = parseJsonText;
    // See also `isExternalOrCommonJsModule` in utilities.ts
    function isExternalModule(file) {
        return file.externalModuleIndicator !== undefined;
    }
    ts.isExternalModule = isExternalModule;
    // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
    // indicates what changed between the 'text' that this SourceFile has and the 'newText'.
    // The SourceFile will be created with the compiler attempting to reuse as many nodes from
    // this file as possible.
    //
    // Note: this function mutates nodes from this SourceFile. That means any existing nodes
    // from this SourceFile that are being held onto may change as a result (including
    // becoming detached from any SourceFile).  It is recommended that this SourceFile not
    // be used once 'update' is called on it.
    function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
        var newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
        // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
        // We will manually port the flag to the new source file.
        newSourceFile.flags |= (sourceFile.flags & 524288 /* PossiblyContainsDynamicImport */);
        return newSourceFile;
    }
    ts.updateSourceFile = updateSourceFile;
    /* @internal */
    function parseIsolatedJSDocComment(content, start, length) {
        var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length);
        if (result && result.jsDoc) {
            // because the jsDocComment was parsed out of the source file, it might
            // not be covered by the fixupParentReferences.
            Parser.fixupParentReferences(result.jsDoc);
        }
        return result;
    }
    ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
    /* @internal */
    // Exposed only for testing.
    function parseJSDocTypeExpressionForTests(content, start, length) {
        return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length);
    }
    ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
    // Implement the parser as a singleton module.  We do this for perf reasons because creating
    // parser instances can actually be expensive enough to impact us on projects with many source
    // files.
    var Parser;
    (function (Parser) {
        // Share a single scanner across all calls to parse a source file.  This helps speed things
        // up by avoiding the cost of creating/compiling scanners over and over again.
        var scanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ true);
        var disallowInAndDecoratorContext = 2048 /* DisallowInContext */ | 8192 /* DecoratorContext */;
        // capture constructors in 'initializeState' to avoid null checks
        var NodeConstructor;
        var TokenConstructor;
        var IdentifierConstructor;
        var SourceFileConstructor;
        var sourceFile;
        var parseDiagnostics;
        var syntaxCursor;
        var currentToken;
        var sourceText;
        var nodeCount;
        var identifiers;
        var identifierCount;
        var parsingContext;
        // Flags that dictate what parsing context we're in.  For example:
        // Whether or not we are in strict parsing mode.  All that changes in strict parsing mode is
        // that some tokens that would be considered identifiers may be considered keywords.
        //
        // When adding more parser context flags, consider which is the more common case that the
        // flag will be in.  This should be the 'false' state for that flag.  The reason for this is
        // that we don't store data in our nodes unless the value is in the *non-default* state.  So,
        // for example, more often than code 'allows-in' (or doesn't 'disallow-in').  We opt for
        // 'disallow-in' set to 'false'.  Otherwise, if we had 'allowsIn' set to 'true', then almost
        // all nodes would need extra state on them to store this info.
        //
        // Note:  'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
        // grammar specification.
        //
        // An important thing about these context concepts.  By default they are effectively inherited
        // while parsing through every grammar production.  i.e. if you don't change them, then when
        // you parse a sub-production, it will have the same context values as the parent production.
        // This is great most of the time.  After all, consider all the 'expression' grammar productions
        // and how nearly all of them pass along the 'in' and 'yield' context values:
        //
        // EqualityExpression[In, Yield] :
        //      RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]
        //
        // Where you have to be careful is then understanding what the points are in the grammar
        // where the values are *not* passed along.  For example:
        //
        // SingleNameBinding[Yield,GeneratorParameter]
        //      [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt
        //      [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
        //
        // Here this is saying that if the GeneratorParameter context flag is set, that we should
        // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier
        // and we should explicitly unset the 'yield' context flag before calling into the Initializer.
        // production.  Conversely, if the GeneratorParameter context flag is not set, then we
        // should leave the 'yield' context flag alone.
        //
        // Getting this all correct is tricky and requires careful reading of the grammar to
        // understand when these values should be changed versus when they should be inherited.
        //
        // Note: it should not be necessary to save/restore these flags during speculative/lookahead
        // parsing.  These context flags are naturally stored and restored through normal recursive
        // descent parsing and unwinding.
        var contextFlags;
        // Whether or not we've had a parse error since creating the last AST node.  If we have
        // encountered an error, it will be stored on the next AST node we create.  Parse errors
        // can be broken down into three categories:
        //
        // 1) An error that occurred during scanning.  For example, an unterminated literal, or a
        //    character that was completely not understood.
        //
        // 2) A token was expected, but was not present.  This type of error is commonly produced
        //    by the 'parseExpected' function.
        //
        // 3) A token was present that no parsing function was able to consume.  This type of error
        //    only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser
        //    decides to skip the token.
        //
        // In all of these cases, we want to mark the next node as having had an error before it.
        // With this mark, we can know in incremental settings if this node can be reused, or if
        // we have to reparse it.  If we don't keep this information around, we may just reuse the
        // node.  in that event we would then not produce the same errors as we did before, causing
        // significant confusion problems.
        //
        // Note: it is necessary that this value be saved/restored during speculative/lookahead
        // parsing.  During lookahead parsing, we will often create a node.  That node will have
        // this value attached, and then this value will be set back to 'false'.  If we decide to
        // rewind, we must get back to the same value we had prior to the lookahead.
        //
        // Note: any errors at the end of the file that do not precede a regular node, should get
        // attached to the EOF token.
        var parseErrorBeforeNextFinishedNode = false;
        function parseSourceFile(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes, scriptKind) {
            scriptKind = ts.ensureScriptKind(fileName, scriptKind);
            initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
            var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
            clearState();
            return result;
        }
        Parser.parseSourceFile = parseSourceFile;
        function parseIsolatedEntityName(content, languageVersion) {
            initializeState(content, languageVersion, /*syntaxCursor*/ undefined, 1 /* JS */);
            // Prime the scanner.
            nextToken();
            var entityName = parseEntityName(/*allowReservedWords*/ true);
            var isInvalid = token() === 1 /* EndOfFileToken */ && !parseDiagnostics.length;
            clearState();
            return isInvalid ? entityName : undefined;
        }
        Parser.parseIsolatedEntityName = parseIsolatedEntityName;
        function parseJsonText(fileName, sourceText) {
            initializeState(sourceText, 2 /* ES2015 */, /*syntaxCursor*/ undefined, 6 /* JSON */);
            // Set source file so that errors will be reported with this file name
            sourceFile = createSourceFile(fileName, 2 /* ES2015 */, 6 /* JSON */);
            var result = sourceFile;
            // Prime the scanner.
            nextToken();
            if (token() === 1 /* EndOfFileToken */) {
                sourceFile.endOfFileToken = parseTokenNode();
            }
            else if (token() === 17 /* OpenBraceToken */ ||
                lookAhead(function () { return token() === 9 /* StringLiteral */; })) {
                result.jsonObject = parseObjectLiteralExpression();
                sourceFile.endOfFileToken = parseExpectedToken(1 /* EndOfFileToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.Unexpected_token);
            }
            else {
                parseExpected(17 /* OpenBraceToken */);
            }
            sourceFile.parseDiagnostics = parseDiagnostics;
            clearState();
            return result;
        }
        Parser.parseJsonText = parseJsonText;
        function getLanguageVariant(scriptKind) {
            // .tsx and .jsx files are treated as jsx language variant.
            return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ || scriptKind === 6 /* JSON */ ? 1 /* JSX */ : 0 /* Standard */;
        }
        function initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind) {
            NodeConstructor = ts.objectAllocator.getNodeConstructor();
            TokenConstructor = ts.objectAllocator.getTokenConstructor();
            IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor();
            SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
            sourceText = _sourceText;
            syntaxCursor = _syntaxCursor;
            parseDiagnostics = [];
            parsingContext = 0;
            identifiers = ts.createMap();
            identifierCount = 0;
            nodeCount = 0;
            contextFlags = scriptKind === 1 /* JS */ || scriptKind === 2 /* JSX */ || scriptKind === 6 /* JSON */ ? 65536 /* JavaScriptFile */ : 0 /* None */;
            parseErrorBeforeNextFinishedNode = false;
            // Initialize and prime the scanner before parsing the source elements.
            scanner.setText(sourceText);
            scanner.setOnError(scanError);
            scanner.setScriptTarget(languageVersion);
            scanner.setLanguageVariant(getLanguageVariant(scriptKind));
        }
        function clearState() {
            // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
            scanner.setText("");
            scanner.setOnError(undefined);
            // Clear any data.  We don't want to accidentally hold onto it for too long.
            parseDiagnostics = undefined;
            sourceFile = undefined;
            identifiers = undefined;
            syntaxCursor = undefined;
            sourceText = undefined;
        }
        function parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind) {
            sourceFile = createSourceFile(fileName, languageVersion, scriptKind);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            processReferenceComments(sourceFile);
            sourceFile.statements = parseList(0 /* SourceElements */, parseStatement);
            ts.Debug.assert(token() === 1 /* EndOfFileToken */);
            sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
            setExternalModuleIndicator(sourceFile);
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            return sourceFile;
        }
        function addJSDocComment(node) {
            var comments = ts.getJSDocCommentRanges(node, sourceFile.text);
            if (comments) {
                for (var _i = 0, comments_2 = comments; _i < comments_2.length; _i++) {
                    var comment = comments_2[_i];
                    var jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
                    if (!jsDoc) {
                        continue;
                    }
                    if (!node.jsDoc) {
                        node.jsDoc = [];
                    }
                    node.jsDoc.push(jsDoc);
                }
            }
            return node;
        }
        function fixupParentReferences(rootNode) {
            // normally parent references are set during binding. However, for clients that only need
            // a syntax tree, and no semantic features, then the binding process is an unnecessary
            // overhead.  This functions allows us to set all the parents, without all the expense of
            // binding.
            var parent = rootNode;
            forEachChild(rootNode, visitNode);
            return;
            function visitNode(n) {
                // walk down setting parents that differ from the parent we think it should be.  This
                // allows us to quickly bail out of setting parents for subtrees during incremental
                // parsing
                if (n.parent !== parent) {
                    n.parent = parent;
                    var saveParent = parent;
                    parent = n;
                    forEachChild(n, visitNode);
                    if (ts.hasJSDocNodes(n)) {
                        for (var _i = 0, _a = n.jsDoc; _i < _a.length; _i++) {
                            var jsDoc = _a[_i];
                            jsDoc.parent = n;
                            parent = jsDoc;
                            forEachChild(jsDoc, visitNode);
                        }
                    }
                    parent = saveParent;
                }
            }
        }
        Parser.fixupParentReferences = fixupParentReferences;
        function createSourceFile(fileName, languageVersion, scriptKind) {
            // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
            // this is quite rare comparing to other nodes and createNode should be as fast as possible
            var sourceFile = new SourceFileConstructor(265 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
            nodeCount++;
            sourceFile.text = sourceText;
            sourceFile.bindDiagnostics = [];
            sourceFile.languageVersion = languageVersion;
            sourceFile.fileName = ts.normalizePath(fileName);
            sourceFile.languageVariant = getLanguageVariant(scriptKind);
            sourceFile.isDeclarationFile = ts.fileExtensionIs(sourceFile.fileName, ".d.ts" /* Dts */);
            sourceFile.scriptKind = scriptKind;
            return sourceFile;
        }
        function setContextFlag(val, flag) {
            if (val) {
                contextFlags |= flag;
            }
            else {
                contextFlags &= ~flag;
            }
        }
        function setDisallowInContext(val) {
            setContextFlag(val, 2048 /* DisallowInContext */);
        }
        function setYieldContext(val) {
            setContextFlag(val, 4096 /* YieldContext */);
        }
        function setDecoratorContext(val) {
            setContextFlag(val, 8192 /* DecoratorContext */);
        }
        function setAwaitContext(val) {
            setContextFlag(val, 16384 /* AwaitContext */);
        }
        function doOutsideOfContext(context, func) {
            // contextFlagsToClear will contain only the context flags that are
            // currently set that we need to temporarily clear
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToClear = context & contextFlags;
            if (contextFlagsToClear) {
                // clear the requested context flags
                setContextFlag(/*val*/ false, contextFlagsToClear);
                var result = func();
                // restore the context flags we just cleared
                setContextFlag(/*val*/ true, contextFlagsToClear);
                return result;
            }
            // no need to do anything special as we are not in any of the requested contexts
            return func();
        }
        function doInsideOfContext(context, func) {
            // contextFlagsToSet will contain only the context flags that
            // are not currently set that we need to temporarily enable.
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToSet = context & ~contextFlags;
            if (contextFlagsToSet) {
                // set the requested context flags
                setContextFlag(/*val*/ true, contextFlagsToSet);
                var result = func();
                // reset the context flags we just set
                setContextFlag(/*val*/ false, contextFlagsToSet);
                return result;
            }
            // no need to do anything special as we are already in all of the requested contexts
            return func();
        }
        function allowInAnd(func) {
            return doOutsideOfContext(2048 /* DisallowInContext */, func);
        }
        function disallowInAnd(func) {
            return doInsideOfContext(2048 /* DisallowInContext */, func);
        }
        function doInYieldContext(func) {
            return doInsideOfContext(4096 /* YieldContext */, func);
        }
        function doInDecoratorContext(func) {
            return doInsideOfContext(8192 /* DecoratorContext */, func);
        }
        function doInAwaitContext(func) {
            return doInsideOfContext(16384 /* AwaitContext */, func);
        }
        function doOutsideOfAwaitContext(func) {
            return doOutsideOfContext(16384 /* AwaitContext */, func);
        }
        function doInYieldAndAwaitContext(func) {
            return doInsideOfContext(4096 /* YieldContext */ | 16384 /* AwaitContext */, func);
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inYieldContext() {
            return inContext(4096 /* YieldContext */);
        }
        function inDisallowInContext() {
            return inContext(2048 /* DisallowInContext */);
        }
        function inDecoratorContext() {
            return inContext(8192 /* DecoratorContext */);
        }
        function inAwaitContext() {
            return inContext(16384 /* AwaitContext */);
        }
        function parseErrorAtCurrentToken(message, arg0) {
            var start = scanner.getTokenPos();
            var length = scanner.getTextPos() - start;
            parseErrorAtPosition(start, length, message, arg0);
        }
        function parseErrorAtPosition(start, length, message, arg0) {
            // Don't report another error if it would just be at the same position as the last error.
            var lastError = ts.lastOrUndefined(parseDiagnostics);
            if (!lastError || start !== lastError.start) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0));
            }
            // Mark that we've encountered an error.  We'll set an appropriate bit on the next
            // node we finish so that it can't be reused incrementally.
            parseErrorBeforeNextFinishedNode = true;
        }
        function scanError(message, length) {
            var pos = scanner.getTextPos();
            parseErrorAtPosition(pos, length || 0, message);
        }
        function getNodePos() {
            return scanner.getStartPos();
        }
        // Use this function to access the current token instead of reading the currentToken
        // variable. Since function results aren't narrowed in control flow analysis, this ensures
        // that the type checker doesn't make wrong assumptions about the type of the current
        // token (e.g. a call to nextToken() changes the current token but the checker doesn't
        // reason about this side effect).  Mainstream VMs inline simple functions like this, so
        // there is no performance penalty.
        function token() {
            return currentToken;
        }
        function nextToken() {
            return currentToken = scanner.scan();
        }
        function reScanGreaterToken() {
            return currentToken = scanner.reScanGreaterToken();
        }
        function reScanSlashToken() {
            return currentToken = scanner.reScanSlashToken();
        }
        function reScanTemplateToken() {
            return currentToken = scanner.reScanTemplateToken();
        }
        function scanJsxIdentifier() {
            return currentToken = scanner.scanJsxIdentifier();
        }
        function scanJsxText() {
            return currentToken = scanner.scanJsxToken();
        }
        function scanJsxAttributeValue() {
            return currentToken = scanner.scanJsxAttributeValue();
        }
        function speculationHelper(callback, isLookAhead) {
            // Keep track of the state we'll need to rollback to if lookahead fails (or if the
            // caller asked us to always reset our state).
            var saveToken = currentToken;
            var saveParseDiagnosticsLength = parseDiagnostics.length;
            var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
            // Note: it is not actually necessary to save/restore the context flags here.  That's
            // because the saving/restoring of these flags happens naturally through the recursive
            // descent nature of our parser.  However, we still store this here just so we can
            // assert that invariant holds.
            var saveContextFlags = contextFlags;
            // If we're only looking ahead, then tell the scanner to only lookahead as well.
            // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the
            // same.
            var result = isLookAhead
                ? scanner.lookAhead(callback)
                : scanner.tryScan(callback);
            ts.Debug.assert(saveContextFlags === contextFlags);
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookAhead) {
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
            }
            return result;
        }
        /** Invokes the provided callback then unconditionally restores the parser to the state it
         * was in immediately prior to invoking the callback.  The result of invoking the callback
         * is returned from this function.
         */
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookAhead*/ true);
        }
        /** Invokes the provided callback.  If the callback returns something falsy, then it restores
         * the parser to the state it was in immediately prior to invoking the callback.  If the
         * callback returns something truthy, then the parser state is not rolled back.  The result
         * of invoking the callback is returned from this function.
         */
        function tryParse(callback) {
            return speculationHelper(callback, /*isLookAhead*/ false);
        }
        // Ignore strict mode flag because we will report an error in type checker instead.
        function isIdentifier() {
            if (token() === 71 /* Identifier */) {
                return true;
            }
            // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is
            // considered a keyword and is not an identifier.
            if (token() === 116 /* YieldKeyword */ && inYieldContext()) {
                return false;
            }
            // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is
            // considered a keyword and is not an identifier.
            if (token() === 121 /* AwaitKeyword */ && inAwaitContext()) {
                return false;
            }
            return token() > 107 /* LastReservedWord */;
        }
        function parseExpected(kind, diagnosticMessage, shouldAdvance) {
            if (shouldAdvance === void 0) { shouldAdvance = true; }
            if (token() === kind) {
                if (shouldAdvance) {
                    nextToken();
                }
                return true;
            }
            // Report specific message if provided with one.  Otherwise, report generic fallback message.
            if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage);
            }
            else {
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            }
            return false;
        }
        function parseOptional(t) {
            if (token() === t) {
                nextToken();
                return true;
            }
            return false;
        }
        function parseOptionalToken(t) {
            if (token() === t) {
                return parseTokenNode();
            }
            return undefined;
        }
        function parseExpectedToken(t, reportAtCurrentPosition, diagnosticMessage, arg0) {
            return parseOptionalToken(t) ||
                createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0);
        }
        function parseTokenNode() {
            var node = createNode(token());
            nextToken();
            return finishNode(node);
        }
        function canParseSemicolon() {
            // If there's a real semicolon, then we can always parse it out.
            if (token() === 25 /* SemicolonToken */) {
                return true;
            }
            // We can parse out an optional semicolon in ASI cases in the following cases.
            return token() === 18 /* CloseBraceToken */ || token() === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
        }
        function parseSemicolon() {
            if (canParseSemicolon()) {
                if (token() === 25 /* SemicolonToken */) {
                    // consume the semicolon if it was explicitly provided.
                    nextToken();
                }
                return true;
            }
            else {
                return parseExpected(25 /* SemicolonToken */);
            }
        }
        // note: this function creates only node
        function createNode(kind, pos) {
            nodeCount++;
            if (!(pos >= 0)) {
                pos = scanner.getStartPos();
            }
            return ts.isNodeKind(kind) ? new NodeConstructor(kind, pos, pos) :
                kind === 71 /* Identifier */ ? new IdentifierConstructor(kind, pos, pos) :
                    new TokenConstructor(kind, pos, pos);
        }
        function createNodeArray(elements, pos, end) {
            // Since the element list of a node array is typically created by starting with an empty array and
            // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
            // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
            var length = elements.length;
            var array = (length >= 1 && length <= 4 ? elements.slice() : elements);
            array.pos = pos;
            array.end = end === undefined ? scanner.getStartPos() : end;
            return array;
        }
        function finishNode(node, end) {
            node.end = end === undefined ? scanner.getStartPos() : end;
            if (contextFlags) {
                node.flags |= contextFlags;
            }
            // Keep track on the node if we encountered an error while parsing it.  If we did, then
            // we cannot reuse the node incrementally.  Once we've marked this node, clear out the
            // flag so that we don't mark any subsequent nodes.
            if (parseErrorBeforeNextFinishedNode) {
                parseErrorBeforeNextFinishedNode = false;
                node.flags |= 32768 /* ThisNodeHasError */;
            }
            return node;
        }
        function createMissingNode(kind, reportAtCurrentPosition, diagnosticMessage, arg0) {
            if (reportAtCurrentPosition) {
                parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
            }
            else {
                parseErrorAtCurrentToken(diagnosticMessage, arg0);
            }
            var result = createNode(kind, scanner.getStartPos());
            if (kind === 71 /* Identifier */) {
                result.escapedText = "";
            }
            else if (ts.isLiteralKind(kind) || ts.isTemplateLiteralKind(kind)) {
                result.text = "";
            }
            return finishNode(result);
        }
        function internIdentifier(text) {
            var identifier = identifiers.get(text);
            if (identifier === undefined) {
                identifiers.set(text, identifier = text);
            }
            return identifier;
        }
        // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
        // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for
        // each identifier in order to reduce memory consumption.
        function createIdentifier(isIdentifier, diagnosticMessage) {
            identifierCount++;
            if (isIdentifier) {
                var node = createNode(71 /* Identifier */);
                // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
                if (token() !== 71 /* Identifier */) {
                    node.originalKeywordKind = token();
                }
                node.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
                nextToken();
                return finishNode(node);
            }
            // Only for end of file because the error gets reported incorrectly on embedded script tags.
            var reportAtCurrentPosition = token() === 1 /* EndOfFileToken */;
            return createMissingNode(71 /* Identifier */, reportAtCurrentPosition, diagnosticMessage || ts.Diagnostics.Identifier_expected);
        }
        function parseIdentifier(diagnosticMessage) {
            return createIdentifier(isIdentifier(), diagnosticMessage);
        }
        function parseIdentifierName(diagnosticMessage) {
            return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage);
        }
        function isLiteralPropertyName() {
            return ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 9 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */;
        }
        function parsePropertyNameWorker(allowComputedPropertyNames) {
            if (token() === 9 /* StringLiteral */ || token() === 8 /* NumericLiteral */) {
                var node = parseLiteralNode();
                node.text = internIdentifier(node.text);
                return node;
            }
            if (allowComputedPropertyNames && token() === 21 /* OpenBracketToken */) {
                return parseComputedPropertyName();
            }
            return parseIdentifierName();
        }
        function parsePropertyName() {
            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
        }
        function parseComputedPropertyName() {
            // PropertyName [Yield]:
            //      LiteralPropertyName
            //      ComputedPropertyName[?Yield]
            var node = createNode(144 /* ComputedPropertyName */);
            parseExpected(21 /* OpenBracketToken */);
            // We parse any expression (including a comma expression). But the grammar
            // says that only an assignment expression is allowed, so the grammar checker
            // will error if it sees a comma expression.
            node.expression = allowInAnd(parseExpression);
            parseExpected(22 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseContextualModifier(t) {
            return token() === t && tryParse(nextTokenCanFollowModifier);
        }
        function nextTokenIsOnSameLineAndCanFollowModifier() {
            nextToken();
            if (scanner.hasPrecedingLineBreak()) {
                return false;
            }
            return canFollowModifier();
        }
        function nextTokenCanFollowModifier() {
            if (token() === 76 /* ConstKeyword */) {
                // 'const' is only a modifier if followed by 'enum'.
                return nextToken() === 83 /* EnumKeyword */;
            }
            if (token() === 84 /* ExportKeyword */) {
                nextToken();
                if (token() === 79 /* DefaultKeyword */) {
                    return lookAhead(nextTokenCanFollowDefaultKeyword);
                }
                return token() !== 39 /* AsteriskToken */ && token() !== 118 /* AsKeyword */ && token() !== 17 /* OpenBraceToken */ && canFollowModifier();
            }
            if (token() === 79 /* DefaultKeyword */) {
                return nextTokenCanFollowDefaultKeyword();
            }
            if (token() === 115 /* StaticKeyword */) {
                nextToken();
                return canFollowModifier();
            }
            return nextTokenIsOnSameLineAndCanFollowModifier();
        }
        function parseAnyContextualModifier() {
            return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier);
        }
        function canFollowModifier() {
            return token() === 21 /* OpenBracketToken */
                || token() === 17 /* OpenBraceToken */
                || token() === 39 /* AsteriskToken */
                || token() === 24 /* DotDotDotToken */
                || isLiteralPropertyName();
        }
        function nextTokenCanFollowDefaultKeyword() {
            nextToken();
            return token() === 75 /* ClassKeyword */ || token() === 89 /* FunctionKeyword */ ||
                token() === 109 /* InterfaceKeyword */ ||
                (token() === 117 /* AbstractKeyword */ && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
                (token() === 120 /* AsyncKeyword */ && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
        }
        // True if positioned at the start of a list element
        function isListElement(parsingContext, inErrorRecovery) {
            var node = currentNode(parsingContext);
            if (node) {
                return true;
            }
            switch (parsingContext) {
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    // If we're in error recovery, then we don't want to treat ';' as an empty statement.
                    // The problem is that ';' can show up in far too many contexts, and if we see one
                    // and assume it's a statement, then we may bail out inappropriately from whatever
                    // we're parsing.  For example, if we have a semicolon in the middle of a class, then
                    // we really don't want to assume the class is over and we're on a statement in the
                    // outer module.  We just want to consume and move on.
                    return !(token() === 25 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement();
                case 2 /* SwitchClauses */:
                    return token() === 73 /* CaseKeyword */ || token() === 79 /* DefaultKeyword */;
                case 4 /* TypeMembers */:
                    return lookAhead(isTypeMemberStart);
                case 5 /* ClassMembers */:
                    // We allow semicolons as class elements (as specified by ES6) as long as we're
                    // not in error recovery.  If we're in error recovery, we don't want an errant
                    // semicolon to be treated as a class member (since they're almost always used
                    // for statements.
                    return lookAhead(isClassMemberStart) || (token() === 25 /* SemicolonToken */ && !inErrorRecovery);
                case 6 /* EnumMembers */:
                    // Include open bracket computed properties. This technically also lets in indexers,
                    // which would be a candidate for improved error reporting.
                    return token() === 21 /* OpenBracketToken */ || isLiteralPropertyName();
                case 12 /* ObjectLiteralMembers */:
                    return token() === 21 /* OpenBracketToken */ || token() === 39 /* AsteriskToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName();
                case 17 /* RestProperties */:
                    return isLiteralPropertyName();
                case 9 /* ObjectBindingElements */:
                    return token() === 21 /* OpenBracketToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName();
                case 7 /* HeritageClauseElement */:
                    // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{`
                    // That way we won't consume the body of a class in its heritage clause.
                    if (token() === 17 /* OpenBraceToken */) {
                        return lookAhead(isValidHeritageClauseObjectLiteral);
                    }
                    if (!inErrorRecovery) {
                        return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                    else {
                        // If we're in error recovery we tighten up what we're willing to match.
                        // That way we don't treat something like "this" as a valid heritage clause
                        // element during recovery.
                        return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                case 8 /* VariableDeclarations */:
                    return isIdentifierOrPattern();
                case 10 /* ArrayBindingElements */:
                    return token() === 26 /* CommaToken */ || token() === 24 /* DotDotDotToken */ || isIdentifierOrPattern();
                case 18 /* TypeParameters */:
                    return isIdentifier();
                case 11 /* ArgumentExpressions */:
                case 15 /* ArrayLiteralMembers */:
                    return token() === 26 /* CommaToken */ || token() === 24 /* DotDotDotToken */ || isStartOfExpression();
                case 16 /* Parameters */:
                    return isStartOfParameter();
                case 19 /* TypeArguments */:
                case 20 /* TupleElementTypes */:
                    return token() === 26 /* CommaToken */ || isStartOfType();
                case 21 /* HeritageClauses */:
                    return isHeritageClause();
                case 22 /* ImportOrExportSpecifiers */:
                    return ts.tokenIsIdentifierOrKeyword(token());
                case 13 /* JsxAttributes */:
                    return ts.tokenIsIdentifierOrKeyword(token()) || token() === 17 /* OpenBraceToken */;
                case 14 /* JsxChildren */:
                    return true;
            }
            ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
        }
        function isValidHeritageClauseObjectLiteral() {
            ts.Debug.assert(token() === 17 /* OpenBraceToken */);
            if (nextToken() === 18 /* CloseBraceToken */) {
                // if we see  "extends {}" then only treat the {} as what we're extending (and not
                // the class body) if we have:
                //
                //      extends {} {
                //      extends {},
                //      extends {} extends
                //      extends {} implements
                var next = nextToken();
                return next === 26 /* CommaToken */ || next === 17 /* OpenBraceToken */ || next === 85 /* ExtendsKeyword */ || next === 108 /* ImplementsKeyword */;
            }
            return true;
        }
        function nextTokenIsIdentifier() {
            nextToken();
            return isIdentifier();
        }
        function nextTokenIsIdentifierOrKeyword() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token());
        }
        function isHeritageClauseExtendsOrImplementsKeyword() {
            if (token() === 108 /* ImplementsKeyword */ ||
                token() === 85 /* ExtendsKeyword */) {
                return lookAhead(nextTokenIsStartOfExpression);
            }
            return false;
        }
        function nextTokenIsStartOfExpression() {
            nextToken();
            return isStartOfExpression();
        }
        // True if positioned at a list terminator
        function isListTerminator(kind) {
            if (token() === 1 /* EndOfFileToken */) {
                // Being at the end of the file ends all lists.
                return true;
            }
            switch (kind) {
                case 1 /* BlockStatements */:
                case 2 /* SwitchClauses */:
                case 4 /* TypeMembers */:
                case 5 /* ClassMembers */:
                case 6 /* EnumMembers */:
                case 12 /* ObjectLiteralMembers */:
                case 9 /* ObjectBindingElements */:
                case 22 /* ImportOrExportSpecifiers */:
                    return token() === 18 /* CloseBraceToken */;
                case 3 /* SwitchClauseStatements */:
                    return token() === 18 /* CloseBraceToken */ || token() === 73 /* CaseKeyword */ || token() === 79 /* DefaultKeyword */;
                case 7 /* HeritageClauseElement */:
                    return token() === 17 /* OpenBraceToken */ || token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */;
                case 8 /* VariableDeclarations */:
                    return isVariableDeclaratorListTerminator();
                case 18 /* TypeParameters */:
                    // Tokens other than '>' are here for better error recovery
                    return token() === 29 /* GreaterThanToken */ || token() === 19 /* OpenParenToken */ || token() === 17 /* OpenBraceToken */ || token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */;
                case 11 /* ArgumentExpressions */:
                    // Tokens other than ')' are here for better error recovery
                    return token() === 20 /* CloseParenToken */ || token() === 25 /* SemicolonToken */;
                case 15 /* ArrayLiteralMembers */:
                case 20 /* TupleElementTypes */:
                case 10 /* ArrayBindingElements */:
                    return token() === 22 /* CloseBracketToken */;
                case 16 /* Parameters */:
                case 17 /* RestProperties */:
                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
                    return token() === 20 /* CloseParenToken */ || token() === 22 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
                case 19 /* TypeArguments */:
                    // All other tokens should cause the type-argument to terminate except comma token
                    return token() !== 26 /* CommaToken */;
                case 21 /* HeritageClauses */:
                    return token() === 17 /* OpenBraceToken */ || token() === 18 /* CloseBraceToken */;
                case 13 /* JsxAttributes */:
                    return token() === 29 /* GreaterThanToken */ || token() === 41 /* SlashToken */;
                case 14 /* JsxChildren */:
                    return token() === 27 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
            }
        }
        function isVariableDeclaratorListTerminator() {
            // If we can consume a semicolon (either explicitly, or with ASI), then consider us done
            // with parsing the list of  variable declarators.
            if (canParseSemicolon()) {
                return true;
            }
            // in the case where we're parsing the variable declarator of a 'for-in' statement, we
            // are done if we see an 'in' keyword in front of us. Same with for-of
            if (isInOrOfKeyword(token())) {
                return true;
            }
            // ERROR RECOVERY TWEAK:
            // For better error recovery, if we see an '=>' then we just stop immediately.  We've got an
            // arrow function here and it's going to be very unlikely that we'll resynchronize and get
            // another variable declaration.
            if (token() === 36 /* EqualsGreaterThanToken */) {
                return true;
            }
            // Keep trying to parse out variable declarators.
            return false;
        }
        // True if positioned at element or terminator of the current list or any enclosing list
        function isInSomeParsingContext() {
            for (var kind = 0; kind < 23 /* Count */; kind++) {
                if (parsingContext & (1 << kind)) {
                    if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Parses a list of elements
        function parseList(kind, parseElement) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            while (!isListTerminator(kind)) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var element = parseListElement(kind, parseElement);
                    list.push(element);
                    continue;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseListElement(parsingContext, parseElement) {
            var node = currentNode(parsingContext);
            if (node) {
                return consumeNode(node);
            }
            return parseElement();
        }
        function currentNode(parsingContext) {
            // If there is an outstanding parse error that we've encountered, but not attached to
            // some node, then we cannot get a node from the old source tree.  This is because we
            // want to mark the next node we encounter as being unusable.
            //
            // Note: This may be too conservative.  Perhaps we could reuse the node and set the bit
            // on it (or its leftmost child) as having the error.  For now though, being conservative
            // is nice and likely won't ever affect perf.
            if (parseErrorBeforeNextFinishedNode) {
                return undefined;
            }
            if (!syntaxCursor) {
                // if we don't have a cursor, we could never return a node from the old tree.
                return undefined;
            }
            var node = syntaxCursor.currentNode(scanner.getStartPos());
            // Can't reuse a missing node.
            if (ts.nodeIsMissing(node)) {
                return undefined;
            }
            // Can't reuse a node that intersected the change range.
            if (node.intersectsChange) {
                return undefined;
            }
            // Can't reuse a node that contains a parse error.  This is necessary so that we
            // produce the same set of errors again.
            if (ts.containsParseError(node)) {
                return undefined;
            }
            // We can only reuse a node if it was parsed under the same strict mode that we're
            // currently in.  i.e. if we originally parsed a node in non-strict mode, but then
            // the user added 'using strict' at the top of the file, then we can't use that node
            // again as the presence of strict mode may cause us to parse the tokens in the file
            // differently.
            //
            // Note: we *can* reuse tokens when the strict mode changes.  That's because tokens
            // are unaffected by strict mode.  It's just the parser will decide what to do with it
            // differently depending on what mode it is in.
            //
            // This also applies to all our other context flags as well.
            var nodeContextFlags = node.flags & 96256 /* ContextFlags */;
            if (nodeContextFlags !== contextFlags) {
                return undefined;
            }
            // Ok, we have a node that looks like it could be reused.  Now verify that it is valid
            // in the current list parsing context that we're currently at.
            if (!canReuseNode(node, parsingContext)) {
                return undefined;
            }
            return node;
        }
        function consumeNode(node) {
            // Move the scanner so it is after the node we just consumed.
            scanner.setTextPos(node.end);
            nextToken();
            return node;
        }
        function canReuseNode(node, parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                    return isReusableClassMember(node);
                case 2 /* SwitchClauses */:
                    return isReusableSwitchClause(node);
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    return isReusableStatement(node);
                case 6 /* EnumMembers */:
                    return isReusableEnumMember(node);
                case 4 /* TypeMembers */:
                    return isReusableTypeMember(node);
                case 8 /* VariableDeclarations */:
                    return isReusableVariableDeclaration(node);
                case 16 /* Parameters */:
                    return isReusableParameter(node);
                case 17 /* RestProperties */:
                    return false;
                // Any other lists we do not care about reusing nodes in.  But feel free to add if
                // you can do so safely.  Danger areas involve nodes that may involve speculative
                // parsing.  If speculative parsing is involved with the node, then the range the
                // parser reached while looking ahead might be in the edited range (see the example
                // in canReuseVariableDeclaratorNode for a good case of this).
                case 21 /* HeritageClauses */:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // heritage clauses.
                case 18 /* TypeParameters */:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // type parameters.  Note that that's because type *parameters* only occur in
                // unambiguous *type* contexts.  While type *arguments* occur in very ambiguous
                // *expression* contexts.
                case 20 /* TupleElementTypes */:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // tuple types.
                // Technically, type argument list types are probably safe to reuse.  While
                // speculative parsing is involved with them (since type argument lists are only
                // produced from speculative parsing a < as a type argument list), we only have
                // the types because speculative parsing succeeded.  Thus, the lookahead never
                // went past the end of the list and rewound.
                case 19 /* TypeArguments */:
                // Note: these are almost certainly not safe to ever reuse.  Expressions commonly
                // need a large amount of lookahead, and we should not reuse them as they may
                // have actually intersected the edit.
                case 11 /* ArgumentExpressions */:
                // This is not safe to reuse for the same reason as the 'AssignmentExpression'
                // cases.  i.e. a property assignment may end with an expression, and thus might
                // have lookahead far beyond it's old node.
                case 12 /* ObjectLiteralMembers */:
                // This is probably not safe to reuse.  There can be speculative parsing with
                // type names in a heritage clause.  There can be generic names in the type
                // name list, and there can be left hand side expressions (which can have type
                // arguments.)
                case 7 /* HeritageClauseElement */:
                // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
                // on any given element. Same for children.
                case 13 /* JsxAttributes */:
                case 14 /* JsxChildren */:
            }
            return false;
        }
        function isReusableClassMember(node) {
            if (node) {
                switch (node.kind) {
                    case 152 /* Constructor */:
                    case 157 /* IndexSignature */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    case 149 /* PropertyDeclaration */:
                    case 206 /* SemicolonClassElement */:
                        return true;
                    case 151 /* MethodDeclaration */:
                        // Method declarations are not necessarily reusable.  An object-literal
                        // may have a method calls "constructor(...)" and we must reparse that
                        // into an actual .ConstructorDeclaration.
                        var methodDeclaration = node;
                        var nameIsConstructor = methodDeclaration.name.kind === 71 /* Identifier */ &&
                            methodDeclaration.name.originalKeywordKind === 123 /* ConstructorKeyword */;
                        return !nameIsConstructor;
                }
            }
            return false;
        }
        function isReusableSwitchClause(node) {
            if (node) {
                switch (node.kind) {
                    case 257 /* CaseClause */:
                    case 258 /* DefaultClause */:
                        return true;
                }
            }
            return false;
        }
        function isReusableStatement(node) {
            if (node) {
                switch (node.kind) {
                    case 228 /* FunctionDeclaration */:
                    case 208 /* VariableStatement */:
                    case 207 /* Block */:
                    case 211 /* IfStatement */:
                    case 210 /* ExpressionStatement */:
                    case 223 /* ThrowStatement */:
                    case 219 /* ReturnStatement */:
                    case 221 /* SwitchStatement */:
                    case 218 /* BreakStatement */:
                    case 217 /* ContinueStatement */:
                    case 215 /* ForInStatement */:
                    case 216 /* ForOfStatement */:
                    case 214 /* ForStatement */:
                    case 213 /* WhileStatement */:
                    case 220 /* WithStatement */:
                    case 209 /* EmptyStatement */:
                    case 224 /* TryStatement */:
                    case 222 /* LabeledStatement */:
                    case 212 /* DoStatement */:
                    case 225 /* DebuggerStatement */:
                    case 238 /* ImportDeclaration */:
                    case 237 /* ImportEqualsDeclaration */:
                    case 244 /* ExportDeclaration */:
                    case 243 /* ExportAssignment */:
                    case 233 /* ModuleDeclaration */:
                    case 229 /* ClassDeclaration */:
                    case 230 /* InterfaceDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 231 /* TypeAliasDeclaration */:
                        return true;
                }
            }
            return false;
        }
        function isReusableEnumMember(node) {
            return node.kind === 264 /* EnumMember */;
        }
        function isReusableTypeMember(node) {
            if (node) {
                switch (node.kind) {
                    case 156 /* ConstructSignature */:
                    case 150 /* MethodSignature */:
                    case 157 /* IndexSignature */:
                    case 148 /* PropertySignature */:
                    case 155 /* CallSignature */:
                        return true;
                }
            }
            return false;
        }
        function isReusableVariableDeclaration(node) {
            if (node.kind !== 226 /* VariableDeclaration */) {
                return false;
            }
            // Very subtle incremental parsing bug.  Consider the following code:
            //
            //      let v = new List < A, B
            //
            // This is actually legal code.  It's a list of variable declarators "v = new List<A"
            // on one side and "B" on the other. If you then change that to:
            //
            //      let v = new List < A, B >()
            //
            // then we have a problem.  "v = new List<A" doesn't intersect the change range, so we
            // start reparsing at "B" and we completely fail to handle this properly.
            //
            // In order to prevent this, we do not allow a variable declarator to be reused if it
            // has an initializer.
            var variableDeclarator = node;
            return variableDeclarator.initializer === undefined;
        }
        function isReusableParameter(node) {
            if (node.kind !== 146 /* Parameter */) {
                return false;
            }
            // See the comment in isReusableVariableDeclaration for why we do this.
            var parameter = node;
            return parameter.initializer === undefined;
        }
        // Returns true if we should abort parsing.
        function abortParsingListOrMoveToNextToken(kind) {
            parseErrorAtCurrentToken(parsingContextErrors(kind));
            if (isInSomeParsingContext()) {
                return true;
            }
            nextToken();
            return false;
        }
        function parsingContextErrors(context) {
            switch (context) {
                case 0 /* SourceElements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 1 /* BlockStatements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 2 /* SwitchClauses */: return ts.Diagnostics.case_or_default_expected;
                case 3 /* SwitchClauseStatements */: return ts.Diagnostics.Statement_expected;
                case 17 /* RestProperties */: // fallthrough
                case 4 /* TypeMembers */: return ts.Diagnostics.Property_or_signature_expected;
                case 5 /* ClassMembers */: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
                case 6 /* EnumMembers */: return ts.Diagnostics.Enum_member_expected;
                case 7 /* HeritageClauseElement */: return ts.Diagnostics.Expression_expected;
                case 8 /* VariableDeclarations */: return ts.Diagnostics.Variable_declaration_expected;
                case 9 /* ObjectBindingElements */: return ts.Diagnostics.Property_destructuring_pattern_expected;
                case 10 /* ArrayBindingElements */: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
                case 11 /* ArgumentExpressions */: return ts.Diagnostics.Argument_expression_expected;
                case 12 /* ObjectLiteralMembers */: return ts.Diagnostics.Property_assignment_expected;
                case 15 /* ArrayLiteralMembers */: return ts.Diagnostics.Expression_or_comma_expected;
                case 16 /* Parameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 18 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
                case 19 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
                case 20 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
                case 21 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected;
                case 22 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected;
                case 13 /* JsxAttributes */: return ts.Diagnostics.Identifier_expected;
                case 14 /* JsxChildren */: return ts.Diagnostics.Identifier_expected;
            }
        }
        // Parses a comma-delimited list of elements
        function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            var commaStart = -1; // Meaning the previous token was not a comma
            while (true) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var startPos = scanner.getStartPos();
                    list.push(parseListElement(kind, parseElement));
                    commaStart = scanner.getTokenPos();
                    if (parseOptional(26 /* CommaToken */)) {
                        // No need to check for a zero length node since we know we parsed a comma
                        continue;
                    }
                    commaStart = -1; // Back to the state where the last token was not a comma
                    if (isListTerminator(kind)) {
                        break;
                    }
                    // We didn't get a comma, and the list wasn't terminated, explicitly parse
                    // out a comma so we give a good error message.
                    parseExpected(26 /* CommaToken */);
                    // If the token was a semicolon, and the caller allows that, then skip it and
                    // continue.  This ensures we get back on track and don't result in tons of
                    // parse errors.  For example, this can happen when people do things like use
                    // a semicolon to delimit object literal members.   Note: we'll have already
                    // reported an error when we called parseExpected above.
                    if (considerSemicolonAsDelimiter && token() === 25 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
                        nextToken();
                    }
                    if (startPos === scanner.getStartPos()) {
                        // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
                        // Consume a token to advance the parser in some way and avoid an infinite loop
                        // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
                        // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
                        nextToken();
                    }
                    continue;
                }
                if (isListTerminator(kind)) {
                    break;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            var result = createNodeArray(list, listPos);
            // Recording the trailing comma is deliberately done after the previous
            // loop, and not just if we see a list terminator. This is because the list
            // may have ended incorrectly, but it is still important to know if there
            // was a trailing comma.
            // Check if the last token was a comma.
            if (commaStart >= 0) {
                // Always preserve a trailing comma by marking it on the NodeArray
                result.hasTrailingComma = true;
            }
            return result;
        }
        function createMissingList() {
            return createNodeArray([], getNodePos());
        }
        function parseBracketedList(kind, parseElement, open, close) {
            if (parseExpected(open)) {
                var result = parseDelimitedList(kind, parseElement);
                parseExpected(close);
                return result;
            }
            return createMissingList();
        }
        function parseEntityName(allowReservedWords, diagnosticMessage) {
            var entity = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
            var dotPos = scanner.getStartPos();
            while (parseOptional(23 /* DotToken */)) {
                if (token() === 27 /* LessThanToken */) {
                    // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting
                    entity.jsdocDotPos = dotPos;
                    break;
                }
                dotPos = scanner.getStartPos();
                entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords));
            }
            return entity;
        }
        function createQualifiedName(entity, name) {
            var node = createNode(143 /* QualifiedName */, entity.pos);
            node.left = entity;
            node.right = name;
            return finishNode(node);
        }
        function parseRightSideOfDot(allowIdentifierNames) {
            // Technically a keyword is valid here as all identifiers and keywords are identifier names.
            // However, often we'll encounter this in error situations when the identifier or keyword
            // is actually starting another valid construct.
            //
            // So, we check for the following specific case:
            //
            //      name.
            //      identifierOrKeyword identifierNameOrKeyword
            //
            // Note: the newlines are important here.  For example, if that above code
            // were rewritten into:
            //
            //      name.identifierOrKeyword
            //      identifierNameOrKeyword
            //
            // Then we would consider it valid.  That's because ASI would take effect and
            // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
            // In the first case though, ASI will not take effect because there is not a
            // line terminator after the identifier or keyword.
            if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) {
                var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                if (matchesPattern) {
                    // Report that we need an identifier.  However, report it right after the dot,
                    // and not on the next token.  This is because the next token might actually
                    // be an identifier and the error would be quite confusing.
                    return createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
                }
            }
            return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
        }
        function parseTemplateExpression() {
            var template = createNode(196 /* TemplateExpression */);
            template.head = parseTemplateHead();
            ts.Debug.assert(template.head.kind === 14 /* TemplateHead */, "Template head has wrong token kind");
            var list = [];
            var listPos = getNodePos();
            do {
                list.push(parseTemplateSpan());
            } while (ts.lastOrUndefined(list).literal.kind === 15 /* TemplateMiddle */);
            template.templateSpans = createNodeArray(list, listPos);
            return finishNode(template);
        }
        function parseTemplateSpan() {
            var span = createNode(205 /* TemplateSpan */);
            span.expression = allowInAnd(parseExpression);
            var literal;
            if (token() === 18 /* CloseBraceToken */) {
                reScanTemplateToken();
                literal = parseTemplateMiddleOrTemplateTail();
            }
            else {
                literal = parseExpectedToken(16 /* TemplateTail */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(18 /* CloseBraceToken */));
            }
            span.literal = literal;
            return finishNode(span);
        }
        function parseLiteralNode() {
            return parseLiteralLikeNode(token());
        }
        function parseTemplateHead() {
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 14 /* TemplateHead */, "Template head has wrong token kind");
            return fragment;
        }
        function parseTemplateMiddleOrTemplateTail() {
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 15 /* TemplateMiddle */ || fragment.kind === 16 /* TemplateTail */, "Template fragment has wrong token kind");
            return fragment;
        }
        function parseLiteralLikeNode(kind) {
            var node = createNode(kind);
            var text = scanner.getTokenValue();
            node.text = text;
            if (scanner.hasExtendedUnicodeEscape()) {
                node.hasExtendedUnicodeEscape = true;
            }
            if (scanner.isUnterminated()) {
                node.isUnterminated = true;
            }
            // Octal literals are not allowed in strict mode or ES5
            // Note that theoretically the following condition would hold true literals like 009,
            // which is not octal.But because of how the scanner separates the tokens, we would
            // never get a token like this. Instead, we would get 00 and 9 as two separate tokens.
            // We also do not need to check for negatives because any prefix operator would be part of a
            // parent unary expression.
            if (node.kind === 8 /* NumericLiteral */) {
                node.numericLiteralFlags = scanner.getNumericLiteralFlags();
            }
            nextToken();
            finishNode(node);
            return node;
        }
        // TYPES
        function parseTypeReference() {
            var node = createNode(159 /* TypeReference */);
            node.typeName = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            if (!scanner.hasPrecedingLineBreak() && token() === 27 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(19 /* TypeArguments */, parseType, 27 /* LessThanToken */, 29 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        function parseThisTypePredicate(lhs) {
            nextToken();
            var node = createNode(158 /* TypePredicate */, lhs.pos);
            node.parameterName = lhs;
            node.type = parseType();
            return finishNode(node);
        }
        function parseThisTypeNode() {
            var node = createNode(169 /* ThisType */);
            nextToken();
            return finishNode(node);
        }
        function parseJSDocAllType() {
            var result = createNode(268 /* JSDocAllType */);
            nextToken();
            return finishNode(result);
        }
        function parseJSDocUnknownOrNullableType() {
            var pos = scanner.getStartPos();
            // skip the ?
            nextToken();
            // Need to lookahead to decide if this is a nullable or unknown type.
            // Here are cases where we'll pick the unknown type:
            //
            //      Foo(?,
            //      { a: ? }
            //      Foo(?)
            //      Foo<?>
            //      Foo(?=
            //      (?|
            if (token() === 26 /* CommaToken */ ||
                token() === 18 /* CloseBraceToken */ ||
                token() === 20 /* CloseParenToken */ ||
                token() === 29 /* GreaterThanToken */ ||
                token() === 58 /* EqualsToken */ ||
                token() === 49 /* BarToken */) {
                var result = createNode(269 /* JSDocUnknownType */, pos);
                return finishNode(result);
            }
            else {
                var result = createNode(270 /* JSDocNullableType */, pos);
                result.type = parseType();
                return finishNode(result);
            }
        }
        function parseJSDocFunctionType() {
            if (lookAhead(nextTokenIsOpenParen)) {
                var result = createNode(273 /* JSDocFunctionType */);
                nextToken();
                fillSignature(56 /* ColonToken */, 4 /* Type */ | 32 /* JSDoc */, result);
                return addJSDocComment(finishNode(result));
            }
            var node = createNode(159 /* TypeReference */);
            node.typeName = parseIdentifierName();
            return finishNode(node);
        }
        function parseJSDocParameter() {
            var parameter = createNode(146 /* Parameter */);
            if (token() === 99 /* ThisKeyword */ || token() === 94 /* NewKeyword */) {
                parameter.name = parseIdentifierName();
                parseExpected(56 /* ColonToken */);
            }
            parameter.type = parseType();
            return finishNode(parameter);
        }
        function parseJSDocNodeWithType(kind) {
            var result = createNode(kind);
            nextToken();
            result.type = parseNonArrayType();
            return finishNode(result);
        }
        function parseTypeQuery() {
            var node = createNode(162 /* TypeQuery */);
            parseExpected(103 /* TypeOfKeyword */);
            node.exprName = parseEntityName(/*allowReservedWords*/ true);
            return finishNode(node);
        }
        function parseTypeParameter() {
            var node = createNode(145 /* TypeParameter */);
            node.name = parseIdentifier();
            if (parseOptional(85 /* ExtendsKeyword */)) {
                // It's not uncommon for people to write improper constraints to a generic.  If the
                // user writes a constraint that is an expression and not an actual type, then parse
                // it out as an expression (so we can recover well), but report that a type is needed
                // instead.
                if (isStartOfType() || !isStartOfExpression()) {
                    node.constraint = parseType();
                }
                else {
                    // It was not a type, and it looked like an expression.  Parse out an expression
                    // here so we recover well.  Note: it is important that we call parseUnaryExpression
                    // and not parseExpression here.  If the user has:
                    //
                    //      <T extends "">
                    //
                    // We do *not* want to consume the  >  as we're consuming the expression for "".
                    node.expression = parseUnaryExpressionOrHigher();
                }
            }
            if (parseOptional(58 /* EqualsToken */)) {
                node.default = parseType();
            }
            return finishNode(node);
        }
        function parseTypeParameters() {
            if (token() === 27 /* LessThanToken */) {
                return parseBracketedList(18 /* TypeParameters */, parseTypeParameter, 27 /* LessThanToken */, 29 /* GreaterThanToken */);
            }
        }
        function parseParameterType() {
            if (parseOptional(56 /* ColonToken */)) {
                return parseType();
            }
            return undefined;
        }
        function isStartOfParameter() {
            return token() === 24 /* DotDotDotToken */ ||
                isIdentifierOrPattern() ||
                ts.isModifierKind(token()) ||
                token() === 57 /* AtToken */ ||
                isStartOfType(/*inStartOfParameter*/ true);
        }
        function parseParameter(requireEqualsToken) {
            var node = createNode(146 /* Parameter */);
            if (token() === 99 /* ThisKeyword */) {
                node.name = createIdentifier(/*isIdentifier*/ true);
                node.type = parseParameterType();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
            // FormalParameter [Yield,Await]:
            //      BindingElement[?Yield,?Await]
            node.name = parseIdentifierOrPattern();
            if (ts.getFullWidth(node.name) === 0 && !ts.hasModifiers(node) && ts.isModifierKind(token())) {
                // in cases like
                // 'use strict'
                // function foo(static)
                // isParameter('static') === true, because of isModifier('static')
                // however 'static' is not a legal identifier in a strict mode.
                // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined)
                // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM)
                // to avoid this we'll advance cursor to the next token.
                nextToken();
            }
            node.questionToken = parseOptionalToken(55 /* QuestionToken */);
            node.type = parseParameterType();
            node.initializer = parseInitializer(/*inParameter*/ true, requireEqualsToken);
            return addJSDocComment(finishNode(node));
        }
        function fillSignature(returnToken, flags, signature) {
            if (!(flags & 32 /* JSDoc */)) {
                signature.typeParameters = parseTypeParameters();
            }
            signature.parameters = parseParameterList(flags);
            signature.type = parseReturnType(returnToken, !!(flags & 4 /* Type */));
        }
        function parseReturnType(returnToken, isType) {
            return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined;
        }
        function shouldParseReturnType(returnToken, isType) {
            if (returnToken === 36 /* EqualsGreaterThanToken */) {
                parseExpected(returnToken);
                return true;
            }
            else if (parseOptional(56 /* ColonToken */)) {
                return true;
            }
            else if (isType && token() === 36 /* EqualsGreaterThanToken */) {
                // This is easy to get backward, especially in type contexts, so parse the type anyway
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(56 /* ColonToken */));
                nextToken();
                return true;
            }
            return false;
        }
        function parseParameterList(flags) {
            // FormalParameters [Yield,Await]: (modified)
            //      [empty]
            //      FormalParameterList[?Yield,Await]
            //
            // FormalParameter[Yield,Await]: (modified)
            //      BindingElement[?Yield,Await]
            //
            // BindingElement [Yield,Await]: (modified)
            //      SingleNameBinding[?Yield,?Await]
            //      BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            //
            // SingleNameBinding [Yield,Await]:
            //      BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            if (parseExpected(19 /* OpenParenToken */)) {
                var savedYieldContext = inYieldContext();
                var savedAwaitContext = inAwaitContext();
                setYieldContext(!!(flags & 1 /* Yield */));
                setAwaitContext(!!(flags & 2 /* Await */));
                var result = parseDelimitedList(16 /* Parameters */, flags & 32 /* JSDoc */ ? parseJSDocParameter : function () { return parseParameter(!!(flags & 8 /* RequireCompleteParameterList */)); });
                setYieldContext(savedYieldContext);
                setAwaitContext(savedAwaitContext);
                if (!parseExpected(20 /* CloseParenToken */) && (flags & 8 /* RequireCompleteParameterList */)) {
                    // Caller insisted that we had to end with a )   We didn't.  So just return
                    // undefined here.
                    return undefined;
                }
                return result;
            }
            // We didn't even have an open paren.  If the caller requires a complete parameter list,
            // we definitely can't provide that.  However, if they're ok with an incomplete one,
            // then just return an empty set of parameters.
            return (flags & 8 /* RequireCompleteParameterList */) ? undefined : createMissingList();
        }
        function parseTypeMemberSemicolon() {
            // We allow type members to be separated by commas or (possibly ASI) semicolons.
            // First check if it was a comma.  If so, we're done with the member.
            if (parseOptional(26 /* CommaToken */)) {
                return;
            }
            // Didn't have a comma.  We must have a (possible ASI) semicolon.
            parseSemicolon();
        }
        function parseSignatureMember(kind) {
            var node = createNode(kind);
            if (kind === 156 /* ConstructSignature */) {
                parseExpected(94 /* NewKeyword */);
            }
            fillSignature(56 /* ColonToken */, 4 /* Type */, node);
            parseTypeMemberSemicolon();
            return addJSDocComment(finishNode(node));
        }
        function isIndexSignature() {
            if (token() !== 21 /* OpenBracketToken */) {
                return false;
            }
            return lookAhead(isUnambiguouslyIndexSignature);
        }
        function isUnambiguouslyIndexSignature() {
            // The only allowed sequence is:
            //
            //   [id:
            //
            // However, for error recovery, we also check the following cases:
            //
            //   [...
            //   [id,
            //   [id?,
            //   [id?:
            //   [id?]
            //   [public id
            //   [private id
            //   [protected id
            //   []
            //
            nextToken();
            if (token() === 24 /* DotDotDotToken */ || token() === 22 /* CloseBracketToken */) {
                return true;
            }
            if (ts.isModifierKind(token())) {
                nextToken();
                if (isIdentifier()) {
                    return true;
                }
            }
            else if (!isIdentifier()) {
                return false;
            }
            else {
                // Skip the identifier
                nextToken();
            }
            // A colon signifies a well formed indexer
            // A comma should be a badly formed indexer because comma expressions are not allowed
            // in computed properties.
            if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */) {
                return true;
            }
            // Question mark could be an indexer with an optional property,
            // or it could be a conditional expression in a computed property.
            if (token() !== 55 /* QuestionToken */) {
                return false;
            }
            // If any of the following tokens are after the question mark, it cannot
            // be a conditional expression, so treat it as an indexer.
            nextToken();
            return token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ || token() === 22 /* CloseBracketToken */;
        }
        function parseIndexSignatureDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(157 /* IndexSignature */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 21 /* OpenBracketToken */, 22 /* CloseBracketToken */);
            node.type = parseTypeAnnotation();
            parseTypeMemberSemicolon();
            return addJSDocComment(finishNode(node));
        }
        function parsePropertyOrMethodSignature(fullStart, modifiers) {
            var name = parsePropertyName();
            var questionToken = parseOptionalToken(55 /* QuestionToken */);
            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
                var method = createNode(150 /* MethodSignature */, fullStart);
                method.modifiers = modifiers;
                method.name = name;
                method.questionToken = questionToken;
                // Method signatures don't exist in expression contexts.  So they have neither
                // [Yield] nor [Await]
                fillSignature(56 /* ColonToken */, 4 /* Type */, method);
                parseTypeMemberSemicolon();
                return addJSDocComment(finishNode(method));
            }
            else {
                var property = createNode(148 /* PropertySignature */, fullStart);
                property.modifiers = modifiers;
                property.name = name;
                property.questionToken = questionToken;
                property.type = parseTypeAnnotation();
                if (token() === 58 /* EqualsToken */) {
                    // Although type literal properties cannot not have initializers, we attempt
                    // to parse an initializer so we can report in the checker that an interface
                    // property or type literal property cannot have an initializer.
                    property.initializer = parseNonParameterInitializer();
                }
                parseTypeMemberSemicolon();
                return addJSDocComment(finishNode(property));
            }
        }
        function isTypeMemberStart() {
            // Return true if we have the start of a signature member
            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
                return true;
            }
            var idToken;
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier
            while (ts.isModifierKind(token())) {
                idToken = true;
                nextToken();
            }
            // Index signatures and computed property names are type members
            if (token() === 21 /* OpenBracketToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers
            if (isLiteralPropertyName()) {
                idToken = true;
                nextToken();
            }
            // If we were able to get any potential identifier, check that it is
            // the start of a member declaration
            if (idToken) {
                return token() === 19 /* OpenParenToken */ ||
                    token() === 27 /* LessThanToken */ ||
                    token() === 55 /* QuestionToken */ ||
                    token() === 56 /* ColonToken */ ||
                    token() === 26 /* CommaToken */ ||
                    canParseSemicolon();
            }
            return false;
        }
        function parseTypeMember() {
            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
                return parseSignatureMember(155 /* CallSignature */);
            }
            if (token() === 94 /* NewKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
                return parseSignatureMember(156 /* ConstructSignature */);
            }
            var fullStart = getNodePos();
            var modifiers = parseModifiers();
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(fullStart, /*decorators*/ undefined, modifiers);
            }
            return parsePropertyOrMethodSignature(fullStart, modifiers);
        }
        function nextTokenIsOpenParenOrLessThan() {
            nextToken();
            return token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */;
        }
        function parseTypeLiteral() {
            var node = createNode(163 /* TypeLiteral */);
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseObjectTypeMembers() {
            var members;
            if (parseExpected(17 /* OpenBraceToken */)) {
                members = parseList(4 /* TypeMembers */, parseTypeMember);
                parseExpected(18 /* CloseBraceToken */);
            }
            else {
                members = createMissingList();
            }
            return members;
        }
        function isStartOfMappedType() {
            nextToken();
            if (token() === 131 /* ReadonlyKeyword */) {
                nextToken();
            }
            return token() === 21 /* OpenBracketToken */ && nextTokenIsIdentifier() && nextToken() === 92 /* InKeyword */;
        }
        function parseMappedTypeParameter() {
            var node = createNode(145 /* TypeParameter */);
            node.name = parseIdentifier();
            parseExpected(92 /* InKeyword */);
            node.constraint = parseType();
            return finishNode(node);
        }
        function parseMappedType() {
            var node = createNode(172 /* MappedType */);
            parseExpected(17 /* OpenBraceToken */);
            node.readonlyToken = parseOptionalToken(131 /* ReadonlyKeyword */);
            parseExpected(21 /* OpenBracketToken */);
            node.typeParameter = parseMappedTypeParameter();
            parseExpected(22 /* CloseBracketToken */);
            node.questionToken = parseOptionalToken(55 /* QuestionToken */);
            node.type = parseTypeAnnotation();
            parseSemicolon();
            parseExpected(18 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseTupleType() {
            var node = createNode(165 /* TupleType */);
            node.elementTypes = parseBracketedList(20 /* TupleElementTypes */, parseType, 21 /* OpenBracketToken */, 22 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseParenthesizedType() {
            var node = createNode(168 /* ParenthesizedType */);
            parseExpected(19 /* OpenParenToken */);
            node.type = parseType();
            parseExpected(20 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseFunctionOrConstructorType(kind) {
            var node = createNode(kind);
            if (kind === 161 /* ConstructorType */) {
                parseExpected(94 /* NewKeyword */);
            }
            fillSignature(36 /* EqualsGreaterThanToken */, 4 /* Type */, node);
            return addJSDocComment(finishNode(node));
        }
        function parseKeywordAndNoDot() {
            var node = parseTokenNode();
            return token() === 23 /* DotToken */ ? undefined : node;
        }
        function parseLiteralTypeNode(negative) {
            var node = createNode(173 /* LiteralType */);
            var unaryMinusExpression;
            if (negative) {
                unaryMinusExpression = createNode(192 /* PrefixUnaryExpression */);
                unaryMinusExpression.operator = 38 /* MinusToken */;
                nextToken();
            }
            var expression = token() === 101 /* TrueKeyword */ || token() === 86 /* FalseKeyword */
                ? parseTokenNode()
                : parseLiteralLikeNode(token());
            if (negative) {
                unaryMinusExpression.operand = expression;
                finishNode(unaryMinusExpression);
                expression = unaryMinusExpression;
            }
            node.literal = expression;
            return finishNode(node);
        }
        function nextTokenIsNumericLiteral() {
            return nextToken() === 8 /* NumericLiteral */;
        }
        function parseNonArrayType() {
            switch (token()) {
                case 119 /* AnyKeyword */:
                case 136 /* StringKeyword */:
                case 133 /* NumberKeyword */:
                case 122 /* BooleanKeyword */:
                case 137 /* SymbolKeyword */:
                case 139 /* UndefinedKeyword */:
                case 130 /* NeverKeyword */:
                case 134 /* ObjectKeyword */:
                    // If these are followed by a dot, then parse these out as a dotted type reference instead.
                    return tryParse(parseKeywordAndNoDot) || parseTypeReference();
                case 39 /* AsteriskToken */:
                    return parseJSDocAllType();
                case 55 /* QuestionToken */:
                    return parseJSDocUnknownOrNullableType();
                case 89 /* FunctionKeyword */:
                    return parseJSDocFunctionType();
                case 24 /* DotDotDotToken */:
                    return parseJSDocNodeWithType(274 /* JSDocVariadicType */);
                case 51 /* ExclamationToken */:
                    return parseJSDocNodeWithType(271 /* JSDocNonNullableType */);
                case 13 /* NoSubstitutionTemplateLiteral */:
                case 9 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 101 /* TrueKeyword */:
                case 86 /* FalseKeyword */:
                    return parseLiteralTypeNode();
                case 38 /* MinusToken */:
                    return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
                case 105 /* VoidKeyword */:
                case 95 /* NullKeyword */:
                    return parseTokenNode();
                case 99 /* ThisKeyword */: {
                    var thisKeyword = parseThisTypeNode();
                    if (token() === 126 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                        return parseThisTypePredicate(thisKeyword);
                    }
                    else {
                        return thisKeyword;
                    }
                }
                case 103 /* TypeOfKeyword */:
                    return parseTypeQuery();
                case 17 /* OpenBraceToken */:
                    return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
                case 21 /* OpenBracketToken */:
                    return parseTupleType();
                case 19 /* OpenParenToken */:
                    return parseParenthesizedType();
                default:
                    return parseTypeReference();
            }
        }
        function isStartOfType(inStartOfParameter) {
            switch (token()) {
                case 119 /* AnyKeyword */:
                case 136 /* StringKeyword */:
                case 133 /* NumberKeyword */:
                case 122 /* BooleanKeyword */:
                case 137 /* SymbolKeyword */:
                case 105 /* VoidKeyword */:
                case 139 /* UndefinedKeyword */:
                case 95 /* NullKeyword */:
                case 99 /* ThisKeyword */:
                case 103 /* TypeOfKeyword */:
                case 130 /* NeverKeyword */:
                case 17 /* OpenBraceToken */:
                case 21 /* OpenBracketToken */:
                case 27 /* LessThanToken */:
                case 49 /* BarToken */:
                case 48 /* AmpersandToken */:
                case 94 /* NewKeyword */:
                case 9 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 101 /* TrueKeyword */:
                case 86 /* FalseKeyword */:
                case 134 /* ObjectKeyword */:
                case 39 /* AsteriskToken */:
                case 55 /* QuestionToken */:
                case 51 /* ExclamationToken */:
                case 24 /* DotDotDotToken */:
                    return true;
                case 38 /* MinusToken */:
                    return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
                case 19 /* OpenParenToken */:
                    // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
                    // or something that starts a type. We don't want to consider things like '(1)' a type.
                    return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfParenthesizedOrFunctionType() {
            nextToken();
            return token() === 20 /* CloseParenToken */ || isStartOfParameter() || isStartOfType();
        }
        function parsePostfixTypeOrHigher() {
            var type = parseNonArrayType();
            while (!scanner.hasPrecedingLineBreak()) {
                switch (token()) {
                    case 58 /* EqualsToken */:
                        // only parse postfix = inside jsdoc, because it's ambiguous elsewhere
                        if (!(contextFlags & 1048576 /* JSDoc */)) {
                            return type;
                        }
                        type = createJSDocPostfixType(272 /* JSDocOptionalType */, type);
                        break;
                    case 51 /* ExclamationToken */:
                        type = createJSDocPostfixType(271 /* JSDocNonNullableType */, type);
                        break;
                    case 55 /* QuestionToken */:
                        type = createJSDocPostfixType(270 /* JSDocNullableType */, type);
                        break;
                    case 21 /* OpenBracketToken */:
                        parseExpected(21 /* OpenBracketToken */);
                        if (isStartOfType()) {
                            var node = createNode(171 /* IndexedAccessType */, type.pos);
                            node.objectType = type;
                            node.indexType = parseType();
                            parseExpected(22 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        else {
                            var node = createNode(164 /* ArrayType */, type.pos);
                            node.elementType = type;
                            parseExpected(22 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        break;
                    default:
                        return type;
                }
            }
            return type;
        }
        function createJSDocPostfixType(kind, type) {
            nextToken();
            var postfix = createNode(kind, type.pos);
            postfix.type = type;
            return finishNode(postfix);
        }
        function parseTypeOperator(operator) {
            var node = createNode(170 /* TypeOperator */);
            parseExpected(operator);
            node.operator = operator;
            node.type = parseTypeOperatorOrHigher();
            return finishNode(node);
        }
        function parseTypeOperatorOrHigher() {
            switch (token()) {
                case 127 /* KeyOfKeyword */:
                    return parseTypeOperator(127 /* KeyOfKeyword */);
            }
            return parsePostfixTypeOrHigher();
        }
        function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
            parseOptional(operator);
            var type = parseConstituentType();
            if (token() === operator) {
                var types = [type];
                while (parseOptional(operator)) {
                    types.push(parseConstituentType());
                }
                var node = createNode(kind, type.pos);
                node.types = createNodeArray(types, type.pos);
                type = finishNode(node);
            }
            return type;
        }
        function parseIntersectionTypeOrHigher() {
            return parseUnionOrIntersectionType(167 /* IntersectionType */, parseTypeOperatorOrHigher, 48 /* AmpersandToken */);
        }
        function parseUnionTypeOrHigher() {
            return parseUnionOrIntersectionType(166 /* UnionType */, parseIntersectionTypeOrHigher, 49 /* BarToken */);
        }
        function isStartOfFunctionType() {
            if (token() === 27 /* LessThanToken */) {
                return true;
            }
            return token() === 19 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType);
        }
        function skipParameterStart() {
            if (ts.isModifierKind(token())) {
                // Skip modifiers
                parseModifiers();
            }
            if (isIdentifier() || token() === 99 /* ThisKeyword */) {
                nextToken();
                return true;
            }
            if (token() === 21 /* OpenBracketToken */ || token() === 17 /* OpenBraceToken */) {
                // Return true if we can parse an array or object binding pattern with no errors
                var previousErrorCount = parseDiagnostics.length;
                parseIdentifierOrPattern();
                return previousErrorCount === parseDiagnostics.length;
            }
            return false;
        }
        function isUnambiguouslyStartOfFunctionType() {
            nextToken();
            if (token() === 20 /* CloseParenToken */ || token() === 24 /* DotDotDotToken */) {
                // ( )
                // ( ...
                return true;
            }
            if (skipParameterStart()) {
                // We successfully skipped modifiers (if any) and an identifier or binding pattern,
                // now see if we have something that indicates a parameter declaration
                if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ ||
                    token() === 55 /* QuestionToken */ || token() === 58 /* EqualsToken */) {
                    // ( xxx :
                    // ( xxx ,
                    // ( xxx ?
                    // ( xxx =
                    return true;
                }
                if (token() === 20 /* CloseParenToken */) {
                    nextToken();
                    if (token() === 36 /* EqualsGreaterThanToken */) {
                        // ( xxx ) =>
                        return true;
                    }
                }
            }
            return false;
        }
        function parseTypeOrTypePredicate() {
            var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix);
            var type = parseType();
            if (typePredicateVariable) {
                var node = createNode(158 /* TypePredicate */, typePredicateVariable.pos);
                node.parameterName = typePredicateVariable;
                node.type = type;
                return finishNode(node);
            }
            else {
                return type;
            }
        }
        function parseTypePredicatePrefix() {
            var id = parseIdentifier();
            if (token() === 126 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                nextToken();
                return id;
            }
        }
        function parseType() {
            // The rules about 'yield' only apply to actual code/expression contexts.  They don't
            // apply to 'type' contexts.  So we disable these parameters here before moving on.
            return doOutsideOfContext(20480 /* TypeExcludesFlags */, parseTypeWorker);
        }
        function parseTypeWorker() {
            if (isStartOfFunctionType()) {
                return parseFunctionOrConstructorType(160 /* FunctionType */);
            }
            if (token() === 94 /* NewKeyword */) {
                return parseFunctionOrConstructorType(161 /* ConstructorType */);
            }
            return parseUnionTypeOrHigher();
        }
        function parseTypeAnnotation() {
            return parseOptional(56 /* ColonToken */) ? parseType() : undefined;
        }
        // EXPRESSIONS
        function isStartOfLeftHandSideExpression() {
            switch (token()) {
                case 99 /* ThisKeyword */:
                case 97 /* SuperKeyword */:
                case 95 /* NullKeyword */:
                case 101 /* TrueKeyword */:
                case 86 /* FalseKeyword */:
                case 8 /* NumericLiteral */:
                case 9 /* StringLiteral */:
                case 13 /* NoSubstitutionTemplateLiteral */:
                case 14 /* TemplateHead */:
                case 19 /* OpenParenToken */:
                case 21 /* OpenBracketToken */:
                case 17 /* OpenBraceToken */:
                case 89 /* FunctionKeyword */:
                case 75 /* ClassKeyword */:
                case 94 /* NewKeyword */:
                case 41 /* SlashToken */:
                case 63 /* SlashEqualsToken */:
                case 71 /* Identifier */:
                    return true;
                case 91 /* ImportKeyword */:
                    return lookAhead(nextTokenIsOpenParenOrLessThan);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfExpression() {
            if (isStartOfLeftHandSideExpression()) {
                return true;
            }
            switch (token()) {
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                case 52 /* TildeToken */:
                case 51 /* ExclamationToken */:
                case 80 /* DeleteKeyword */:
                case 103 /* TypeOfKeyword */:
                case 105 /* VoidKeyword */:
                case 43 /* PlusPlusToken */:
                case 44 /* MinusMinusToken */:
                case 27 /* LessThanToken */:
                case 121 /* AwaitKeyword */:
                case 116 /* YieldKeyword */:
                    // Yield/await always starts an expression.  Either it is an identifier (in which case
                    // it is definitely an expression).  Or it's a keyword (either because we're in
                    // a generator or async function, or in strict mode (or both)) and it started a yield or await expression.
                    return true;
                default:
                    // Error tolerance.  If we see the start of some binary operator, we consider
                    // that the start of an expression.  That way we'll parse out a missing identifier,
                    // give a good message about an identifier being missing, and then consume the
                    // rest of the binary expression.
                    if (isBinaryOperator()) {
                        return true;
                    }
                    return isIdentifier();
            }
        }
        function isStartOfExpressionStatement() {
            // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement.
            return token() !== 17 /* OpenBraceToken */ &&
                token() !== 89 /* FunctionKeyword */ &&
                token() !== 75 /* ClassKeyword */ &&
                token() !== 57 /* AtToken */ &&
                isStartOfExpression();
        }
        function parseExpression() {
            // Expression[in]:
            //      AssignmentExpression[in]
            //      Expression[in] , AssignmentExpression[in]
            // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var expr = parseAssignmentExpressionOrHigher();
            var operatorToken;
            while ((operatorToken = parseOptionalToken(26 /* CommaToken */))) {
                expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
            }
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return expr;
        }
        function parseInitializer(inParameter, requireEqualsToken) {
            if (token() !== 58 /* EqualsToken */) {
                // It's not uncommon during typing for the user to miss writing the '=' token.  Check if
                // there is no newline after the last token and if we're on an expression.  If so, parse
                // this as an equals-value clause with a missing equals.
                // NOTE: There are two places where we allow equals-value clauses.  The first is in a
                // variable declarator.  The second is with a parameter.  For variable declarators
                // it's more likely that a { would be a allowed (as an object literal).  While this
                // is also allowed for parameters, the risk is that we consume the { as an object
                // literal when it really will be for the block following the parameter.
                if (scanner.hasPrecedingLineBreak() || (inParameter && token() === 17 /* OpenBraceToken */) || !isStartOfExpression()) {
                    // preceding line break, open brace in a parameter (likely a function body) or current token is not an expression -
                    // do not try to parse initializer
                    return undefined;
                }
                if (inParameter && requireEqualsToken) {
                    // = is required when speculatively parsing arrow function parameters,
                    // so return a fake initializer as a signal that the equals token was missing
                    var result = createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics._0_expected, "=");
                    result.escapedText = "= not found";
                    return result;
                }
            }
            // Initializer[In, Yield] :
            //     = AssignmentExpression[?In, ?Yield]
            parseExpected(58 /* EqualsToken */);
            return parseAssignmentExpressionOrHigher();
        }
        function parseAssignmentExpressionOrHigher() {
            //  AssignmentExpression[in,yield]:
            //      1) ConditionalExpression[?in,?yield]
            //      2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
            //      3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
            //      4) ArrowFunctionExpression[?in,?yield]
            //      5) AsyncArrowFunctionExpression[in,yield,await]
            //      6) [+Yield] YieldExpression[?In]
            //
            // Note: for ease of implementation we treat productions '2' and '3' as the same thing.
            // (i.e. they're both BinaryExpressions with an assignment operator in it).
            // First, do the simple check if we have a YieldExpression (production '6').
            if (isYieldExpression()) {
                return parseYieldExpression();
            }
            // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized
            // parameter list or is an async arrow function.
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression".
            // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
            //
            // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
            // not a  LeftHandSideExpression, nor does it start a ConditionalExpression.  So we are done
            // with AssignmentExpression if we see one.
            var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
            if (arrowExpression) {
                return arrowExpression;
            }
            // Now try to see if we're in production '1', '2' or '3'.  A conditional expression can
            // start with a LogicalOrExpression, while the assignment productions can only start with
            // LeftHandSideExpressions.
            //
            // So, first, we try to just parse out a BinaryExpression.  If we get something that is a
            // LeftHandSide or higher, then we can try to parse out the assignment expression part.
            // Otherwise, we try to parse out the conditional expression bit.  We want to allow any
            // binary expression here, so we pass in the 'lowest' precedence here so that it matches
            // and consumes anything.
            var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
            // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
            // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
            // identifier and the current token is an arrow.
            if (expr.kind === 71 /* Identifier */ && token() === 36 /* EqualsGreaterThanToken */) {
                return parseSimpleArrowFunctionExpression(expr);
            }
            // Now see if we might be in cases '2' or '3'.
            // If the expression was a LHS expression, and we have an assignment operator, then
            // we're in '2' or '3'. Consume the assignment and return.
            //
            // Note: we call reScanGreaterToken so that we get an appropriately merged token
            // for cases like > > =  becoming >>=
            if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
                return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
            }
            // It wasn't an assignment or a lambda.  This is a conditional expression:
            return parseConditionalExpressionRest(expr);
        }
        function isYieldExpression() {
            if (token() === 116 /* YieldKeyword */) {
                // If we have a 'yield' keyword, and this is a context where yield expressions are
                // allowed, then definitely parse out a yield expression.
                if (inYieldContext()) {
                    return true;
                }
                // We're in a context where 'yield expr' is not allowed.  However, if we can
                // definitely tell that the user was trying to parse a 'yield expr' and not
                // just a normal expr that start with a 'yield' identifier, then parse out
                // a 'yield expr'.  We can then report an error later that they are only
                // allowed in generator expressions.
                //
                // for example, if we see 'yield(foo)', then we'll have to treat that as an
                // invocation expression of something called 'yield'.  However, if we have
                // 'yield foo' then that is not legal as a normal expression, so we can
                // definitely recognize this as a yield expression.
                //
                // for now we just check if the next token is an identifier.  More heuristics
                // can be added here later as necessary.  We just need to make sure that we
                // don't accidentally consume something legal.
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function nextTokenIsIdentifierOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && isIdentifier();
        }
        function parseYieldExpression() {
            var node = createNode(197 /* YieldExpression */);
            // YieldExpression[In] :
            //      yield
            //      yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            //      yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            nextToken();
            if (!scanner.hasPrecedingLineBreak() &&
                (token() === 39 /* AsteriskToken */ || isStartOfExpression())) {
                node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            else {
                // if the next token is not on the same line as yield.  or we don't have an '*' or
                // the start of an expression, then this is just a simple "yield" expression.
                return finishNode(node);
            }
        }
        function parseSimpleArrowFunctionExpression(identifier, asyncModifier) {
            ts.Debug.assert(token() === 36 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
            var node;
            if (asyncModifier) {
                node = createNode(187 /* ArrowFunction */, asyncModifier.pos);
                node.modifiers = asyncModifier;
            }
            else {
                node = createNode(187 /* ArrowFunction */, identifier.pos);
            }
            var parameter = createNode(146 /* Parameter */, identifier.pos);
            parameter.name = identifier;
            finishNode(parameter);
            node.parameters = createNodeArray([parameter], parameter.pos, parameter.end);
            node.equalsGreaterThanToken = parseExpectedToken(36 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>");
            node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
            return addJSDocComment(finishNode(node));
        }
        function tryParseParenthesizedArrowFunctionExpression() {
            var triState = isParenthesizedArrowFunctionExpression();
            if (triState === 0 /* False */) {
                // It's definitely not a parenthesized arrow function expression.
                return undefined;
            }
            // If we definitely have an arrow function, then we can just parse one, not requiring a
            // following => or { token. Otherwise, we *might* have an arrow function.  Try to parse
            // it out, but don't allow any ambiguity, and return 'undefined' if this could be an
            // expression instead.
            var arrowFunction = triState === 1 /* True */
                ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true)
                : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
            if (!arrowFunction) {
                // Didn't appear to actually be a parenthesized arrow function.  Just bail out.
                return undefined;
            }
            var isAsync = ts.hasModifier(arrowFunction, 256 /* Async */);
            // If we have an arrow, then try to parse the body. Even if not, try to parse if we
            // have an opening brace, just in case we're in an error state.
            var lastToken = token();
            arrowFunction.equalsGreaterThanToken = parseExpectedToken(36 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>");
            arrowFunction.body = (lastToken === 36 /* EqualsGreaterThanToken */ || lastToken === 17 /* OpenBraceToken */)
                ? parseArrowFunctionExpressionBody(isAsync)
                : parseIdentifier();
            return addJSDocComment(finishNode(arrowFunction));
        }
        //  True        -> We definitely expect a parenthesized arrow function here.
        //  False       -> There *cannot* be a parenthesized arrow function here.
        //  Unknown     -> There *might* be a parenthesized arrow function here.
        //                 Speculatively look ahead to be sure, and rollback if not.
        function isParenthesizedArrowFunctionExpression() {
            if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */ || token() === 120 /* AsyncKeyword */) {
                return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
            }
            if (token() === 36 /* EqualsGreaterThanToken */) {
                // ERROR RECOVERY TWEAK:
                // If we see a standalone => try to parse it as an arrow function expression as that's
                // likely what the user intended to write.
                return 1 /* True */;
            }
            // Definitely not a parenthesized arrow function.
            return 0 /* False */;
        }
        function isParenthesizedArrowFunctionExpressionWorker() {
            if (token() === 120 /* AsyncKeyword */) {
                nextToken();
                if (scanner.hasPrecedingLineBreak()) {
                    return 0 /* False */;
                }
                if (token() !== 19 /* OpenParenToken */ && token() !== 27 /* LessThanToken */) {
                    return 0 /* False */;
                }
            }
            var first = token();
            var second = nextToken();
            if (first === 19 /* OpenParenToken */) {
                if (second === 20 /* CloseParenToken */) {
                    // Simple cases: "() =>", "(): ", and  "() {".
                    // This is an arrow function with no parameters.
                    // The last one is not actually an arrow function,
                    // but this is probably what the user intended.
                    var third = nextToken();
                    switch (third) {
                        case 36 /* EqualsGreaterThanToken */:
                        case 56 /* ColonToken */:
                        case 17 /* OpenBraceToken */:
                            return 1 /* True */;
                        default:
                            return 0 /* False */;
                    }
                }
                // If encounter "([" or "({", this could be the start of a binding pattern.
                // Examples:
                //      ([ x ]) => { }
                //      ({ x }) => { }
                //      ([ x ])
                //      ({ x })
                if (second === 21 /* OpenBracketToken */ || second === 17 /* OpenBraceToken */) {
                    return 2 /* Unknown */;
                }
                // Simple case: "(..."
                // This is an arrow function with a rest parameter.
                if (second === 24 /* DotDotDotToken */) {
                    return 1 /* True */;
                }
                // If we had "(" followed by something that's not an identifier,
                // then this definitely doesn't look like a lambda.
                // Note: we could be a little more lenient and allow
                // "(public" or "(private". These would not ever actually be allowed,
                // but we could provide a good error message instead of bailing out.
                if (!isIdentifier()) {
                    return 0 /* False */;
                }
                // If we have something like "(a:", then we must have a
                // type-annotated parameter in an arrow function expression.
                if (nextToken() === 56 /* ColonToken */) {
                    return 1 /* True */;
                }
                // This *could* be a parenthesized arrow function.
                // Return Unknown to let the caller know.
                return 2 /* Unknown */;
            }
            else {
                ts.Debug.assert(first === 27 /* LessThanToken */);
                // If we have "<" not followed by an identifier,
                // then this definitely is not an arrow function.
                if (!isIdentifier()) {
                    return 0 /* False */;
                }
                // JSX overrides
                if (sourceFile.languageVariant === 1 /* JSX */) {
                    var isArrowFunctionInJsx = lookAhead(function () {
                        var third = nextToken();
                        if (third === 85 /* ExtendsKeyword */) {
                            var fourth = nextToken();
                            switch (fourth) {
                                case 58 /* EqualsToken */:
                                case 29 /* GreaterThanToken */:
                                    return false;
                                default:
                                    return true;
                            }
                        }
                        else if (third === 26 /* CommaToken */) {
                            return true;
                        }
                        return false;
                    });
                    if (isArrowFunctionInJsx) {
                        return 1 /* True */;
                    }
                    return 0 /* False */;
                }
                // This *could* be a parenthesized arrow function.
                return 2 /* Unknown */;
            }
        }
        function parsePossibleParenthesizedArrowFunctionExpressionHead() {
            return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
        }
        function tryParseAsyncSimpleArrowFunctionExpression() {
            // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
            if (token() === 120 /* AsyncKeyword */) {
                if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) {
                    var asyncModifier = parseModifiersForArrowFunction();
                    var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                    return parseSimpleArrowFunctionExpression(expr, asyncModifier);
                }
            }
            return undefined;
        }
        function isUnParenthesizedAsyncArrowFunctionWorker() {
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            if (token() === 120 /* AsyncKeyword */) {
                nextToken();
                // If the "async" is followed by "=>" token then it is not a begining of an async arrow-function
                // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher"
                if (scanner.hasPrecedingLineBreak() || token() === 36 /* EqualsGreaterThanToken */) {
                    return 0 /* False */;
                }
                // Check for un-parenthesized AsyncArrowFunction
                var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                if (!scanner.hasPrecedingLineBreak() && expr.kind === 71 /* Identifier */ && token() === 36 /* EqualsGreaterThanToken */) {
                    return 1 /* True */;
                }
            }
            return 0 /* False */;
        }
        function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
            var node = createNode(187 /* ArrowFunction */);
            node.modifiers = parseModifiersForArrowFunction();
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            // Arrow functions are never generators.
            //
            // If we're speculatively parsing a signature for a parenthesized arrow function, then
            // we have to have a complete parameter list.  Otherwise we might see something like
            // a => (b => c)
            // And think that "(b =>" was actually a parenthesized arrow function with a missing
            // close paren.
            fillSignature(56 /* ColonToken */, isAsync | (allowAmbiguity ? 0 /* None */ : 8 /* RequireCompleteParameterList */), node);
            // If we couldn't get parameters, we definitely could not parse out an arrow function.
            if (!node.parameters) {
                return undefined;
            }
            // Parsing a signature isn't enough.
            // Parenthesized arrow signatures often look like other valid expressions.
            // For instance:
            //  - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value.
            //  - "(x,y)" is a comma expression parsed as a signature with two parameters.
            //  - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
            //
            // So we need just a bit of lookahead to ensure that it can only be a signature.
            if (!allowAmbiguity && ((token() !== 36 /* EqualsGreaterThanToken */ && token() !== 17 /* OpenBraceToken */) ||
                ts.find(node.parameters, function (p) { return p.initializer && ts.isIdentifier(p.initializer) && p.initializer.escapedText === "= not found"; }))) {
                // Returning undefined here will cause our caller to rewind to where we started from.
                return undefined;
            }
            return node;
        }
        function parseArrowFunctionExpressionBody(isAsync) {
            if (token() === 17 /* OpenBraceToken */) {
                return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */);
            }
            if (token() !== 25 /* SemicolonToken */ &&
                token() !== 89 /* FunctionKeyword */ &&
                token() !== 75 /* ClassKeyword */ &&
                isStartOfStatement() &&
                !isStartOfExpressionStatement()) {
                // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations)
                //
                // Here we try to recover from a potential error situation in the case where the
                // user meant to supply a block. For example, if the user wrote:
                //
                //  a =>
                //      let v = 0;
                //  }
                //
                // they may be missing an open brace.  Check to see if that's the case so we can
                // try to recover better.  If we don't do this, then the next close curly we see may end
                // up preemptively closing the containing construct.
                //
                // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error.
                return parseFunctionBlock(16 /* IgnoreMissingOpenBrace */ | (isAsync ? 2 /* Await */ : 0 /* None */));
            }
            return isAsync
                ? doInAwaitContext(parseAssignmentExpressionOrHigher)
                : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
        }
        function parseConditionalExpressionRest(leftOperand) {
            // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher.
            var questionToken = parseOptionalToken(55 /* QuestionToken */);
            if (!questionToken) {
                return leftOperand;
            }
            // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
            // we do not that for the 'whenFalse' part.
            var node = createNode(195 /* ConditionalExpression */, leftOperand.pos);
            node.condition = leftOperand;
            node.questionToken = questionToken;
            node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
            node.colonToken = parseExpectedToken(56 /* ColonToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(56 /* ColonToken */));
            node.whenFalse = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseBinaryExpressionOrHigher(precedence) {
            var leftOperand = parseUnaryExpressionOrHigher();
            return parseBinaryExpressionRest(precedence, leftOperand);
        }
        function isInOrOfKeyword(t) {
            return t === 92 /* InKeyword */ || t === 142 /* OfKeyword */;
        }
        function parseBinaryExpressionRest(precedence, leftOperand) {
            while (true) {
                // We either have a binary operator here, or we're finished.  We call
                // reScanGreaterToken so that we merge token sequences like > and = into >=
                reScanGreaterToken();
                var newPrecedence = getBinaryOperatorPrecedence();
                // Check the precedence to see if we should "take" this operator
                // - For left associative operator (all operator but **), consume the operator,
                //   recursively call the function below, and parse binaryExpression as a rightOperand
                //   of the caller if the new precedence of the operator is greater then or equal to the current precedence.
                //   For example:
                //      a - b - c;
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a * b - c
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a - b * c;
                //            ^token; leftOperand = b. Return b * c to the caller as a rightOperand
                // - For right associative operator (**), consume the operator, recursively call the function
                //   and parse binaryExpression as a rightOperand of the caller if the new precedence of
                //   the operator is strictly grater than the current precedence
                //   For example:
                //      a ** b ** c;
                //             ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a - b ** c;
                //            ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a ** b - c
                //             ^token; leftOperand = b. Return b to the caller as a rightOperand
                var consumeCurrentOperator = token() === 40 /* AsteriskAsteriskToken */ ?
                    newPrecedence >= precedence :
                    newPrecedence > precedence;
                if (!consumeCurrentOperator) {
                    break;
                }
                if (token() === 92 /* InKeyword */ && inDisallowInContext()) {
                    break;
                }
                if (token() === 118 /* AsKeyword */) {
                    // Make sure we *do* perform ASI for constructs like this:
                    //    var x = foo
                    //    as (Bar)
                    // This should be parsed as an initialized variable, followed
                    // by a function call to 'as' with the argument 'Bar'
                    if (scanner.hasPrecedingLineBreak()) {
                        break;
                    }
                    else {
                        nextToken();
                        leftOperand = makeAsExpression(leftOperand, parseType());
                    }
                }
                else {
                    leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
                }
            }
            return leftOperand;
        }
        function isBinaryOperator() {
            if (inDisallowInContext() && token() === 92 /* InKeyword */) {
                return false;
            }
            return getBinaryOperatorPrecedence() > 0;
        }
        function getBinaryOperatorPrecedence() {
            switch (token()) {
                case 54 /* BarBarToken */:
                    return 1;
                case 53 /* AmpersandAmpersandToken */:
                    return 2;
                case 49 /* BarToken */:
                    return 3;
                case 50 /* CaretToken */:
                    return 4;
                case 48 /* AmpersandToken */:
                    return 5;
                case 32 /* EqualsEqualsToken */:
                case 33 /* ExclamationEqualsToken */:
                case 34 /* EqualsEqualsEqualsToken */:
                case 35 /* ExclamationEqualsEqualsToken */:
                    return 6;
                case 27 /* LessThanToken */:
                case 29 /* GreaterThanToken */:
                case 30 /* LessThanEqualsToken */:
                case 31 /* GreaterThanEqualsToken */:
                case 93 /* InstanceOfKeyword */:
                case 92 /* InKeyword */:
                case 118 /* AsKeyword */:
                    return 7;
                case 45 /* LessThanLessThanToken */:
                case 46 /* GreaterThanGreaterThanToken */:
                case 47 /* GreaterThanGreaterThanGreaterThanToken */:
                    return 8;
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                    return 9;
                case 39 /* AsteriskToken */:
                case 41 /* SlashToken */:
                case 42 /* PercentToken */:
                    return 10;
                case 40 /* AsteriskAsteriskToken */:
                    return 11;
            }
            // -1 is lower than all other precedences.  Returning it will cause binary expression
            // parsing to stop.
            return -1;
        }
        function makeBinaryExpression(left, operatorToken, right) {
            var node = createNode(194 /* BinaryExpression */, left.pos);
            node.left = left;
            node.operatorToken = operatorToken;
            node.right = right;
            return finishNode(node);
        }
        function makeAsExpression(left, right) {
            var node = createNode(202 /* AsExpression */, left.pos);
            node.expression = left;
            node.type = right;
            return finishNode(node);
        }
        function parsePrefixUnaryExpression() {
            var node = createNode(192 /* PrefixUnaryExpression */);
            node.operator = token();
            nextToken();
            node.operand = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseDeleteExpression() {
            var node = createNode(188 /* DeleteExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseTypeOfExpression() {
            var node = createNode(189 /* TypeOfExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseVoidExpression() {
            var node = createNode(190 /* VoidExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function isAwaitExpression() {
            if (token() === 121 /* AwaitKeyword */) {
                if (inAwaitContext()) {
                    return true;
                }
                // here we are using similar heuristics as 'isYieldExpression'
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function parseAwaitExpression() {
            var node = createNode(191 /* AwaitExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        /**
         * Parse ES7 exponential expression and await expression
         *
         * ES7 ExponentiationExpression:
         *      1) UnaryExpression[?Yield]
         *      2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]
         *
         */
        function parseUnaryExpressionOrHigher() {
            /**
             * ES7 UpdateExpression:
             *      1) LeftHandSideExpression[?Yield]
             *      2) LeftHandSideExpression[?Yield][no LineTerminator here]++
             *      3) LeftHandSideExpression[?Yield][no LineTerminator here]--
             *      4) ++UnaryExpression[?Yield]
             *      5) --UnaryExpression[?Yield]
             */
            if (isUpdateExpression()) {
                var updateExpression = parseUpdateExpression();
                return token() === 40 /* AsteriskAsteriskToken */ ?
                    parseBinaryExpressionRest(getBinaryOperatorPrecedence(), updateExpression) :
                    updateExpression;
            }
            /**
             * ES7 UnaryExpression:
             *      1) UpdateExpression[?yield]
             *      2) delete UpdateExpression[?yield]
             *      3) void UpdateExpression[?yield]
             *      4) typeof UpdateExpression[?yield]
             *      5) + UpdateExpression[?yield]
             *      6) - UpdateExpression[?yield]
             *      7) ~ UpdateExpression[?yield]
             *      8) ! UpdateExpression[?yield]
             */
            var unaryOperator = token();
            var simpleUnaryExpression = parseSimpleUnaryExpression();
            if (token() === 40 /* AsteriskAsteriskToken */) {
                var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
                if (simpleUnaryExpression.kind === 184 /* TypeAssertionExpression */) {
                    parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
                }
                else {
                    parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
                }
            }
            return simpleUnaryExpression;
        }
        /**
         * Parse ES7 simple-unary expression or higher:
         *
         * ES7 UnaryExpression:
         *      1) UpdateExpression[?yield]
         *      2) delete UnaryExpression[?yield]
         *      3) void UnaryExpression[?yield]
         *      4) typeof UnaryExpression[?yield]
         *      5) + UnaryExpression[?yield]
         *      6) - UnaryExpression[?yield]
         *      7) ~ UnaryExpression[?yield]
         *      8) ! UnaryExpression[?yield]
         *      9) [+Await] await UnaryExpression[?yield]
         */
        function parseSimpleUnaryExpression() {
            switch (token()) {
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                case 52 /* TildeToken */:
                case 51 /* ExclamationToken */:
                    return parsePrefixUnaryExpression();
                case 80 /* DeleteKeyword */:
                    return parseDeleteExpression();
                case 103 /* TypeOfKeyword */:
                    return parseTypeOfExpression();
                case 105 /* VoidKeyword */:
                    return parseVoidExpression();
                case 27 /* LessThanToken */:
                    // This is modified UnaryExpression grammar in TypeScript
                    //  UnaryExpression (modified):
                    //      < type > UnaryExpression
                    return parseTypeAssertion();
                case 121 /* AwaitKeyword */:
                    if (isAwaitExpression()) {
                        return parseAwaitExpression();
                    }
                // falls through
                default:
                    return parseUpdateExpression();
            }
        }
        /**
         * Check if the current token can possibly be an ES7 increment expression.
         *
         * ES7 UpdateExpression:
         *      LeftHandSideExpression[?Yield]
         *      LeftHandSideExpression[?Yield][no LineTerminator here]++
         *      LeftHandSideExpression[?Yield][no LineTerminator here]--
         *      ++LeftHandSideExpression[?Yield]
         *      --LeftHandSideExpression[?Yield]
         */
        function isUpdateExpression() {
            // This function is called inside parseUnaryExpression to decide
            // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly
            switch (token()) {
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                case 52 /* TildeToken */:
                case 51 /* ExclamationToken */:
                case 80 /* DeleteKeyword */:
                case 103 /* TypeOfKeyword */:
                case 105 /* VoidKeyword */:
                case 121 /* AwaitKeyword */:
                    return false;
                case 27 /* LessThanToken */:
                    // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
                    if (sourceFile.languageVariant !== 1 /* JSX */) {
                        return false;
                    }
                // We are in JSX context and the token is part of JSXElement.
                // falls through
                default:
                    return true;
            }
        }
        /**
         * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression.
         *
         * ES7 UpdateExpression[yield]:
         *      1) LeftHandSideExpression[?yield]
         *      2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
         *      3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
         *      4) ++LeftHandSideExpression[?yield]
         *      5) --LeftHandSideExpression[?yield]
         * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
         */
        function parseUpdateExpression() {
            if (token() === 43 /* PlusPlusToken */ || token() === 44 /* MinusMinusToken */) {
                var node = createNode(192 /* PrefixUnaryExpression */);
                node.operator = token();
                nextToken();
                node.operand = parseLeftHandSideExpressionOrHigher();
                return finishNode(node);
            }
            else if (sourceFile.languageVariant === 1 /* JSX */ && token() === 27 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
                // JSXElement is part of primaryExpression
                return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
            }
            var expression = parseLeftHandSideExpressionOrHigher();
            ts.Debug.assert(ts.isLeftHandSideExpression(expression));
            if ((token() === 43 /* PlusPlusToken */ || token() === 44 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
                var node = createNode(193 /* PostfixUnaryExpression */, expression.pos);
                node.operand = expression;
                node.operator = token();
                nextToken();
                return finishNode(node);
            }
            return expression;
        }
        function parseLeftHandSideExpressionOrHigher() {
            // Original Ecma:
            // LeftHandSideExpression: See 11.2
            //      NewExpression
            //      CallExpression
            //
            // Our simplification:
            //
            // LeftHandSideExpression: See 11.2
            //      MemberExpression
            //      CallExpression
            //
            // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
            // MemberExpression to make our lives easier.
            //
            // to best understand the below code, it's important to see how CallExpression expands
            // out into its own productions:
            //
            // CallExpression:
            //      MemberExpression Arguments
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //      import (AssignmentExpression)
            //      super Arguments
            //      super.IdentifierName
            //
            // Because of the recursion in these calls, we need to bottom out first. There are three
            // bottom out states we can run into: 1) We see 'super' which must start either of
            // the last two CallExpression productions. 2) We see 'import' which must start import call.
            // 3)we have a MemberExpression which either completes the LeftHandSideExpression,
            // or starts the beginning of the first four CallExpression productions.
            var expression;
            if (token() === 91 /* ImportKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
                // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "("
                // For example:
                //      var foo3 = require("subfolder
                //      import * as foo1 from "module-from-node  -> we want this import to be a statement rather than import call expression
                sourceFile.flags |= 524288 /* PossiblyContainsDynamicImport */;
                expression = parseTokenNode();
            }
            else {
                expression = token() === 97 /* SuperKeyword */ ? parseSuperExpression() : parseMemberExpressionOrHigher();
            }
            // Now, we *may* be complete.  However, we might have consumed the start of a
            // CallExpression.  As such, we need to consume the rest of it here to be complete.
            return parseCallExpressionRest(expression);
        }
        function parseMemberExpressionOrHigher() {
            // Note: to make our lives simpler, we decompose the NewExpression productions and
            // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
            // like so:
            //
            //   PrimaryExpression : See 11.1
            //      this
            //      Identifier
            //      Literal
            //      ArrayLiteral
            //      ObjectLiteral
            //      (Expression)
            //      FunctionExpression
            //      new MemberExpression Arguments?
            //
            //   MemberExpression : See 11.2
            //      PrimaryExpression
            //      MemberExpression[Expression]
            //      MemberExpression.IdentifierName
            //
            //   CallExpression : See 11.2
            //      MemberExpression
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //
            // Technically this is ambiguous.  i.e. CallExpression defines:
            //
            //   CallExpression:
            //      CallExpression Arguments
            //
            // If you see: "new Foo()"
            //
            // Then that could be treated as a single ObjectCreationExpression, or it could be
            // treated as the invocation of "new Foo".  We disambiguate that in code (to match
            // the original grammar) by making sure that if we see an ObjectCreationExpression
            // we always consume arguments if they are there. So we treat "new Foo()" as an
            // object creation only, and not at all as an invocation)  Another way to think
            // about this is that for every "new" that we see, we will consume an argument list if
            // it is there as part of the *associated* object creation node.  Any additional
            // argument lists we see, will become invocation expressions.
            //
            // Because there are no other places in the grammar now that refer to FunctionExpression
            // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
            // production.
            //
            // Because CallExpression and MemberExpression are left recursive, we need to bottom out
            // of the recursion immediately.  So we parse out a primary expression to start with.
            var expression = parsePrimaryExpression();
            return parseMemberExpressionRest(expression);
        }
        function parseSuperExpression() {
            var expression = parseTokenNode();
            if (token() === 19 /* OpenParenToken */ || token() === 23 /* DotToken */ || token() === 21 /* OpenBracketToken */) {
                return expression;
            }
            // If we have seen "super" it must be followed by '(' or '.'.
            // If it wasn't then just try to parse out a '.' and report an error.
            var node = createNode(179 /* PropertyAccessExpression */, expression.pos);
            node.expression = expression;
            parseExpectedToken(23 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
            node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
            return finishNode(node);
        }
        function tagNamesAreEquivalent(lhs, rhs) {
            if (lhs.kind !== rhs.kind) {
                return false;
            }
            if (lhs.kind === 71 /* Identifier */) {
                return lhs.escapedText === rhs.escapedText;
            }
            if (lhs.kind === 99 /* ThisKeyword */) {
                return true;
            }
            // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
            // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
            // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
            return lhs.name.escapedText === rhs.name.escapedText &&
                tagNamesAreEquivalent(lhs.expression, rhs.expression);
        }
        function parseJsxElementOrSelfClosingElement(inExpressionContext) {
            var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
            var result;
            if (opening.kind === 251 /* JsxOpeningElement */) {
                var node = createNode(249 /* JsxElement */, opening.pos);
                node.openingElement = opening;
                node.children = parseJsxChildren(node.openingElement.tagName);
                node.closingElement = parseJsxClosingElement(inExpressionContext);
                if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
                    parseErrorAtPosition(node.closingElement.pos, node.closingElement.end - node.closingElement.pos, ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName));
                }
                result = finishNode(node);
            }
            else {
                ts.Debug.assert(opening.kind === 250 /* JsxSelfClosingElement */);
                // Nothing else to do for self-closing elements
                result = opening;
            }
            // If the user writes the invalid code '<div></div><div></div>' in an expression context (i.e. not wrapped in
            // an enclosing tag), we'll naively try to parse   ^ this as a 'less than' operator and the remainder of the tag
            // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
            // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
            // does less damage and we can report a better error.
            // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
            // of one sort or another.
            if (inExpressionContext && token() === 27 /* LessThanToken */) {
                var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
                if (invalidElement) {
                    parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
                    var badNode = createNode(194 /* BinaryExpression */, result.pos);
                    badNode.end = invalidElement.end;
                    badNode.left = result;
                    badNode.right = invalidElement;
                    badNode.operatorToken = createMissingNode(26 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
                    badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
                    return badNode;
                }
            }
            return result;
        }
        function parseJsxText() {
            var node = createNode(10 /* JsxText */, scanner.getStartPos());
            node.containsOnlyWhiteSpaces = currentToken === 11 /* JsxTextAllWhiteSpaces */;
            currentToken = scanner.scanJsxToken();
            return finishNode(node);
        }
        function parseJsxChild() {
            switch (token()) {
                case 10 /* JsxText */:
                case 11 /* JsxTextAllWhiteSpaces */:
                    return parseJsxText();
                case 17 /* OpenBraceToken */:
                    return parseJsxExpression(/*inExpressionContext*/ false);
                case 27 /* LessThanToken */:
                    return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
            }
            ts.Debug.fail("Unknown JSX child kind " + token());
        }
        function parseJsxChildren(openingTagName) {
            var list = [];
            var listPos = getNodePos();
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << 14 /* JsxChildren */;
            while (true) {
                currentToken = scanner.reScanJsxToken();
                if (token() === 28 /* LessThanSlashToken */) {
                    // Closing tag
                    break;
                }
                else if (token() === 1 /* EndOfFileToken */) {
                    // If we hit EOF, issue the error at the tag that lacks the closing element
                    // rather than at the end of the file (which is useless)
                    parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
                    break;
                }
                else if (token() === 7 /* ConflictMarkerTrivia */) {
                    break;
                }
                var child = parseJsxChild();
                if (child) {
                    list.push(child);
                }
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseJsxAttributes() {
            var jsxAttributes = createNode(254 /* JsxAttributes */);
            jsxAttributes.properties = parseList(13 /* JsxAttributes */, parseJsxAttribute);
            return finishNode(jsxAttributes);
        }
        function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
            var fullStart = scanner.getStartPos();
            parseExpected(27 /* LessThanToken */);
            var tagName = parseJsxElementName();
            var attributes = parseJsxAttributes();
            var node;
            if (token() === 29 /* GreaterThanToken */) {
                // Closing tag, so scan the immediately-following text with the JSX scanning instead
                // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
                // scanning errors
                node = createNode(251 /* JsxOpeningElement */, fullStart);
                scanJsxText();
            }
            else {
                parseExpected(41 /* SlashToken */);
                if (inExpressionContext) {
                    parseExpected(29 /* GreaterThanToken */);
                }
                else {
                    parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                    scanJsxText();
                }
                node = createNode(250 /* JsxSelfClosingElement */, fullStart);
            }
            node.tagName = tagName;
            node.attributes = attributes;
            return finishNode(node);
        }
        function parseJsxElementName() {
            scanJsxIdentifier();
            // JsxElement can have name in the form of
            //      propertyAccessExpression
            //      primaryExpression in the form of an identifier and "this" keyword
            // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
            // We only want to consider "this" as a primaryExpression
            var expression = token() === 99 /* ThisKeyword */ ?
                parseTokenNode() : parseIdentifierName();
            while (parseOptional(23 /* DotToken */)) {
                var propertyAccess = createNode(179 /* PropertyAccessExpression */, expression.pos);
                propertyAccess.expression = expression;
                propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
                expression = finishNode(propertyAccess);
            }
            return expression;
        }
        function parseJsxExpression(inExpressionContext) {
            var node = createNode(256 /* JsxExpression */);
            parseExpected(17 /* OpenBraceToken */);
            if (token() !== 18 /* CloseBraceToken */) {
                node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
                node.expression = parseAssignmentExpressionOrHigher();
            }
            if (inExpressionContext) {
                parseExpected(18 /* CloseBraceToken */);
            }
            else {
                parseExpected(18 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseJsxAttribute() {
            if (token() === 17 /* OpenBraceToken */) {
                return parseJsxSpreadAttribute();
            }
            scanJsxIdentifier();
            var node = createNode(253 /* JsxAttribute */);
            node.name = parseIdentifierName();
            if (token() === 58 /* EqualsToken */) {
                switch (scanJsxAttributeValue()) {
                    case 9 /* StringLiteral */:
                        node.initializer = parseLiteralNode();
                        break;
                    default:
                        node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
                        break;
                }
            }
            return finishNode(node);
        }
        function parseJsxSpreadAttribute() {
            var node = createNode(255 /* JsxSpreadAttribute */);
            parseExpected(17 /* OpenBraceToken */);
            parseExpected(24 /* DotDotDotToken */);
            node.expression = parseExpression();
            parseExpected(18 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseJsxClosingElement(inExpressionContext) {
            var node = createNode(252 /* JsxClosingElement */);
            parseExpected(28 /* LessThanSlashToken */);
            node.tagName = parseJsxElementName();
            if (inExpressionContext) {
                parseExpected(29 /* GreaterThanToken */);
            }
            else {
                parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseTypeAssertion() {
            var node = createNode(184 /* TypeAssertionExpression */);
            parseExpected(27 /* LessThanToken */);
            node.type = parseType();
            parseExpected(29 /* GreaterThanToken */);
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseMemberExpressionRest(expression) {
            while (true) {
                var dotToken = parseOptionalToken(23 /* DotToken */);
                if (dotToken) {
                    var propertyAccess = createNode(179 /* PropertyAccessExpression */, expression.pos);
                    propertyAccess.expression = expression;
                    propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
                    expression = finishNode(propertyAccess);
                    continue;
                }
                if (token() === 51 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                    nextToken();
                    var nonNullExpression = createNode(203 /* NonNullExpression */, expression.pos);
                    nonNullExpression.expression = expression;
                    expression = finishNode(nonNullExpression);
                    continue;
                }
                // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
                if (!inDecoratorContext() && parseOptional(21 /* OpenBracketToken */)) {
                    var indexedAccess = createNode(180 /* ElementAccessExpression */, expression.pos);
                    indexedAccess.expression = expression;
                    // It's not uncommon for a user to write: "new Type[]".
                    // Check for that common pattern and report a better error message.
                    if (token() !== 22 /* CloseBracketToken */) {
                        indexedAccess.argumentExpression = allowInAnd(parseExpression);
                        if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) {
                            var literal = indexedAccess.argumentExpression;
                            literal.text = internIdentifier(literal.text);
                        }
                    }
                    parseExpected(22 /* CloseBracketToken */);
                    expression = finishNode(indexedAccess);
                    continue;
                }
                if (token() === 13 /* NoSubstitutionTemplateLiteral */ || token() === 14 /* TemplateHead */) {
                    var tagExpression = createNode(183 /* TaggedTemplateExpression */, expression.pos);
                    tagExpression.tag = expression;
                    tagExpression.template = token() === 13 /* NoSubstitutionTemplateLiteral */
                        ? parseLiteralNode()
                        : parseTemplateExpression();
                    expression = finishNode(tagExpression);
                    continue;
                }
                return expression;
            }
        }
        function parseCallExpressionRest(expression) {
            while (true) {
                expression = parseMemberExpressionRest(expression);
                if (token() === 27 /* LessThanToken */) {
                    // See if this is the start of a generic invocation.  If so, consume it and
                    // keep checking for postfix expressions.  Otherwise, it's just a '<' that's
                    // part of an arithmetic expression.  Break out so we consume it higher in the
                    // stack.
                    var typeArguments = tryParse(parseTypeArgumentsInExpression);
                    if (!typeArguments) {
                        return expression;
                    }
                    var callExpr = createNode(181 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.typeArguments = typeArguments;
                    callExpr.arguments = parseArgumentList();
                    expression = finishNode(callExpr);
                    continue;
                }
                else if (token() === 19 /* OpenParenToken */) {
                    var callExpr = createNode(181 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.arguments = parseArgumentList();
                    expression = finishNode(callExpr);
                    continue;
                }
                return expression;
            }
        }
        function parseArgumentList() {
            parseExpected(19 /* OpenParenToken */);
            var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
            parseExpected(20 /* CloseParenToken */);
            return result;
        }
        function parseTypeArgumentsInExpression() {
            if (!parseOptional(27 /* LessThanToken */)) {
                return undefined;
            }
            var typeArguments = parseDelimitedList(19 /* TypeArguments */, parseType);
            if (!parseExpected(29 /* GreaterThanToken */)) {
                // If it doesn't have the closing >  then it's definitely not an type argument list.
                return undefined;
            }
            // If we have a '<', then only parse this as a argument list if the type arguments
            // are complete and we have an open paren.  if we don't, rewind and return nothing.
            return typeArguments && canFollowTypeArgumentsInExpression()
                ? typeArguments
                : undefined;
        }
        function canFollowTypeArgumentsInExpression() {
            switch (token()) {
                case 19 /* OpenParenToken */: // foo<x>(
                // this case are the only case where this token can legally follow a type argument
                // list.  So we definitely want to treat this as a type arg list.
                case 23 /* DotToken */: // foo<x>.
                case 20 /* CloseParenToken */: // foo<x>)
                case 22 /* CloseBracketToken */: // foo<x>]
                case 56 /* ColonToken */: // foo<x>:
                case 25 /* SemicolonToken */: // foo<x>;
                case 55 /* QuestionToken */: // foo<x>?
                case 32 /* EqualsEqualsToken */: // foo<x> ==
                case 34 /* EqualsEqualsEqualsToken */: // foo<x> ===
                case 33 /* ExclamationEqualsToken */: // foo<x> !=
                case 35 /* ExclamationEqualsEqualsToken */: // foo<x> !==
                case 53 /* AmpersandAmpersandToken */: // foo<x> &&
                case 54 /* BarBarToken */: // foo<x> ||
                case 50 /* CaretToken */: // foo<x> ^
                case 48 /* AmpersandToken */: // foo<x> &
                case 49 /* BarToken */: // foo<x> |
                case 18 /* CloseBraceToken */: // foo<x> }
                case 1 /* EndOfFileToken */:// foo<x>
                    // these cases can't legally follow a type arg list.  However, they're not legal
                    // expressions either.  The user is probably in the middle of a generic type. So
                    // treat it as such.
                    return true;
                case 26 /* CommaToken */: // foo<x>,
                case 17 /* OpenBraceToken */: // foo<x> {
                // We don't want to treat these as type arguments.  Otherwise we'll parse this
                // as an invocation expression.  Instead, we want to parse out the expression
                // in isolation from the type arguments.
                default:
                    // Anything else treat as an expression.
                    return false;
            }
        }
        function parsePrimaryExpression() {
            switch (token()) {
                case 8 /* NumericLiteral */:
                case 9 /* StringLiteral */:
                case 13 /* NoSubstitutionTemplateLiteral */:
                    return parseLiteralNode();
                case 99 /* ThisKeyword */:
                case 97 /* SuperKeyword */:
                case 95 /* NullKeyword */:
                case 101 /* TrueKeyword */:
                case 86 /* FalseKeyword */:
                    return parseTokenNode();
                case 19 /* OpenParenToken */:
                    return parseParenthesizedExpression();
                case 21 /* OpenBracketToken */:
                    return parseArrayLiteralExpression();
                case 17 /* OpenBraceToken */:
                    return parseObjectLiteralExpression();
                case 120 /* AsyncKeyword */:
                    // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
                    // If we encounter `async [no LineTerminator here] function` then this is an async
                    // function; otherwise, its an identifier.
                    if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
                        break;
                    }
                    return parseFunctionExpression();
                case 75 /* ClassKeyword */:
                    return parseClassExpression();
                case 89 /* FunctionKeyword */:
                    return parseFunctionExpression();
                case 94 /* NewKeyword */:
                    return parseNewExpression();
                case 41 /* SlashToken */:
                case 63 /* SlashEqualsToken */:
                    if (reScanSlashToken() === 12 /* RegularExpressionLiteral */) {
                        return parseLiteralNode();
                    }
                    break;
                case 14 /* TemplateHead */:
                    return parseTemplateExpression();
            }
            return parseIdentifier(ts.Diagnostics.Expression_expected);
        }
        function parseParenthesizedExpression() {
            var node = createNode(185 /* ParenthesizedExpression */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(20 /* CloseParenToken */);
            return addJSDocComment(finishNode(node));
        }
        function parseSpreadElement() {
            var node = createNode(198 /* SpreadElement */);
            parseExpected(24 /* DotDotDotToken */);
            node.expression = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseArgumentOrArrayLiteralElement() {
            return token() === 24 /* DotDotDotToken */ ? parseSpreadElement() :
                token() === 26 /* CommaToken */ ? createNode(200 /* OmittedExpression */) :
                    parseAssignmentExpressionOrHigher();
        }
        function parseArgumentExpression() {
            return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
        }
        function parseArrayLiteralExpression() {
            var node = createNode(177 /* ArrayLiteralExpression */);
            parseExpected(21 /* OpenBracketToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
            parseExpected(22 /* CloseBracketToken */);
            return finishNode(node);
        }
        function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
            if (parseContextualModifier(125 /* GetKeyword */)) {
                return parseAccessorDeclaration(153 /* GetAccessor */, fullStart, decorators, modifiers);
            }
            else if (parseContextualModifier(135 /* SetKeyword */)) {
                return parseAccessorDeclaration(154 /* SetAccessor */, fullStart, decorators, modifiers);
            }
            return undefined;
        }
        function parseObjectLiteralElement() {
            var fullStart = scanner.getStartPos();
            var dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
            if (dotDotDotToken) {
                var spreadElement = createNode(263 /* SpreadAssignment */, fullStart);
                spreadElement.expression = parseAssignmentExpressionOrHigher();
                return addJSDocComment(finishNode(spreadElement));
            }
            var decorators = parseDecorators();
            var modifiers = parseModifiers();
            var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
            if (accessor) {
                return accessor;
            }
            var asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            // Disallowing of optional property assignments happens in the grammar checker.
            var questionToken = parseOptionalToken(55 /* QuestionToken */);
            if (asteriskToken || token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
                return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
            }
            // check if it is short-hand property assignment or normal property assignment
            // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
            // CoverInitializedName[Yield] :
            //     IdentifierReference[?Yield] Initializer[In, ?Yield]
            // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
            var isShorthandPropertyAssignment = tokenIsIdentifier && (token() === 26 /* CommaToken */ || token() === 18 /* CloseBraceToken */ || token() === 58 /* EqualsToken */);
            if (isShorthandPropertyAssignment) {
                var shorthandDeclaration = createNode(262 /* ShorthandPropertyAssignment */, fullStart);
                shorthandDeclaration.name = propertyName;
                shorthandDeclaration.questionToken = questionToken;
                var equalsToken = parseOptionalToken(58 /* EqualsToken */);
                if (equalsToken) {
                    shorthandDeclaration.equalsToken = equalsToken;
                    shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
                }
                return addJSDocComment(finishNode(shorthandDeclaration));
            }
            else {
                var propertyAssignment = createNode(261 /* PropertyAssignment */, fullStart);
                propertyAssignment.modifiers = modifiers;
                propertyAssignment.name = propertyName;
                propertyAssignment.questionToken = questionToken;
                parseExpected(56 /* ColonToken */);
                propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
                return addJSDocComment(finishNode(propertyAssignment));
            }
        }
        function parseObjectLiteralExpression() {
            var node = createNode(178 /* ObjectLiteralExpression */);
            parseExpected(17 /* OpenBraceToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
            parseExpected(18 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseFunctionExpression() {
            // GeneratorExpression:
            //      function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
            //
            // FunctionExpression:
            //      function BindingIdentifier[opt](FormalParameters){ FunctionBody }
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var node = createNode(186 /* FunctionExpression */);
            node.modifiers = parseModifiers();
            parseExpected(89 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            node.name =
                isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
                    isGenerator ? doInYieldContext(parseOptionalIdentifier) :
                        isAsync ? doInAwaitContext(parseOptionalIdentifier) :
                            parseOptionalIdentifier();
            fillSignature(56 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlock(isGenerator | isAsync);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return addJSDocComment(finishNode(node));
        }
        function parseOptionalIdentifier() {
            return isIdentifier() ? parseIdentifier() : undefined;
        }
        function parseNewExpression() {
            var fullStart = scanner.getStartPos();
            parseExpected(94 /* NewKeyword */);
            if (parseOptional(23 /* DotToken */)) {
                var node_1 = createNode(204 /* MetaProperty */, fullStart);
                node_1.keywordToken = 94 /* NewKeyword */;
                node_1.name = parseIdentifierName();
                return finishNode(node_1);
            }
            var node = createNode(182 /* NewExpression */, fullStart);
            node.expression = parseMemberExpressionOrHigher();
            node.typeArguments = tryParse(parseTypeArgumentsInExpression);
            if (node.typeArguments || token() === 19 /* OpenParenToken */) {
                node.arguments = parseArgumentList();
            }
            return finishNode(node);
        }
        // STATEMENTS
        function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
            var node = createNode(207 /* Block */);
            if (parseExpected(17 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
                if (scanner.hasPrecedingLineBreak()) {
                    node.multiLine = true;
                }
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(18 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseFunctionBlock(flags, diagnosticMessage) {
            var savedYieldContext = inYieldContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            var savedAwaitContext = inAwaitContext();
            setAwaitContext(!!(flags & 2 /* Await */));
            // We may be in a [Decorator] context when parsing a function expression or
            // arrow function. The body of the function is not in [Decorator] context.
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var block = parseBlock(!!(flags & 16 /* IgnoreMissingOpenBrace */), diagnosticMessage);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return block;
        }
        function parseEmptyStatement() {
            var node = createNode(209 /* EmptyStatement */);
            parseExpected(25 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseIfStatement() {
            var node = createNode(211 /* IfStatement */);
            parseExpected(90 /* IfKeyword */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(20 /* CloseParenToken */);
            node.thenStatement = parseStatement();
            node.elseStatement = parseOptional(82 /* ElseKeyword */) ? parseStatement() : undefined;
            return finishNode(node);
        }
        function parseDoStatement() {
            var node = createNode(212 /* DoStatement */);
            parseExpected(81 /* DoKeyword */);
            node.statement = parseStatement();
            parseExpected(106 /* WhileKeyword */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(20 /* CloseParenToken */);
            // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
            // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
            // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
            //  do;while(0)x will have a semicolon inserted before x.
            parseOptional(25 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseWhileStatement() {
            var node = createNode(213 /* WhileStatement */);
            parseExpected(106 /* WhileKeyword */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(20 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseForOrForInOrForOfStatement() {
            var pos = getNodePos();
            parseExpected(88 /* ForKeyword */);
            var awaitToken = parseOptionalToken(121 /* AwaitKeyword */);
            parseExpected(19 /* OpenParenToken */);
            var initializer = undefined;
            if (token() !== 25 /* SemicolonToken */) {
                if (token() === 104 /* VarKeyword */ || token() === 110 /* LetKeyword */ || token() === 76 /* ConstKeyword */) {
                    initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
                }
                else {
                    initializer = disallowInAnd(parseExpression);
                }
            }
            var forOrForInOrForOfStatement;
            if (awaitToken ? parseExpected(142 /* OfKeyword */) : parseOptional(142 /* OfKeyword */)) {
                var forOfStatement = createNode(216 /* ForOfStatement */, pos);
                forOfStatement.awaitModifier = awaitToken;
                forOfStatement.initializer = initializer;
                forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
                parseExpected(20 /* CloseParenToken */);
                forOrForInOrForOfStatement = forOfStatement;
            }
            else if (parseOptional(92 /* InKeyword */)) {
                var forInStatement = createNode(215 /* ForInStatement */, pos);
                forInStatement.initializer = initializer;
                forInStatement.expression = allowInAnd(parseExpression);
                parseExpected(20 /* CloseParenToken */);
                forOrForInOrForOfStatement = forInStatement;
            }
            else {
                var forStatement = createNode(214 /* ForStatement */, pos);
                forStatement.initializer = initializer;
                parseExpected(25 /* SemicolonToken */);
                if (token() !== 25 /* SemicolonToken */ && token() !== 20 /* CloseParenToken */) {
                    forStatement.condition = allowInAnd(parseExpression);
                }
                parseExpected(25 /* SemicolonToken */);
                if (token() !== 20 /* CloseParenToken */) {
                    forStatement.incrementor = allowInAnd(parseExpression);
                }
                parseExpected(20 /* CloseParenToken */);
                forOrForInOrForOfStatement = forStatement;
            }
            forOrForInOrForOfStatement.statement = parseStatement();
            return finishNode(forOrForInOrForOfStatement);
        }
        function parseBreakOrContinueStatement(kind) {
            var node = createNode(kind);
            parseExpected(kind === 218 /* BreakStatement */ ? 72 /* BreakKeyword */ : 77 /* ContinueKeyword */);
            if (!canParseSemicolon()) {
                node.label = parseIdentifier();
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseReturnStatement() {
            var node = createNode(219 /* ReturnStatement */);
            parseExpected(96 /* ReturnKeyword */);
            if (!canParseSemicolon()) {
                node.expression = allowInAnd(parseExpression);
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseWithStatement() {
            var node = createNode(220 /* WithStatement */);
            parseExpected(107 /* WithKeyword */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(20 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseCaseClause() {
            var node = createNode(257 /* CaseClause */);
            parseExpected(73 /* CaseKeyword */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(56 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseDefaultClause() {
            var node = createNode(258 /* DefaultClause */);
            parseExpected(79 /* DefaultKeyword */);
            parseExpected(56 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseCaseOrDefaultClause() {
            return token() === 73 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
        }
        function parseSwitchStatement() {
            var node = createNode(221 /* SwitchStatement */);
            parseExpected(98 /* SwitchKeyword */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(20 /* CloseParenToken */);
            var caseBlock = createNode(235 /* CaseBlock */, scanner.getStartPos());
            parseExpected(17 /* OpenBraceToken */);
            caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
            parseExpected(18 /* CloseBraceToken */);
            node.caseBlock = finishNode(caseBlock);
            return finishNode(node);
        }
        function parseThrowStatement() {
            // ThrowStatement[Yield] :
            //      throw [no LineTerminator here]Expression[In, ?Yield];
            // Because of automatic semicolon insertion, we need to report error if this
            // throw could be terminated with a semicolon.  Note: we can't call 'parseExpression'
            // directly as that might consume an expression on the following line.
            // We just return 'undefined' in that case.  The actual error will be reported in the
            // grammar walker.
            var node = createNode(223 /* ThrowStatement */);
            parseExpected(100 /* ThrowKeyword */);
            node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
            parseSemicolon();
            return finishNode(node);
        }
        // TODO: Review for error recovery
        function parseTryStatement() {
            var node = createNode(224 /* TryStatement */);
            parseExpected(102 /* TryKeyword */);
            node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            node.catchClause = token() === 74 /* CatchKeyword */ ? parseCatchClause() : undefined;
            // If we don't have a catch clause, then we must have a finally clause.  Try to parse
            // one out no matter what.
            if (!node.catchClause || token() === 87 /* FinallyKeyword */) {
                parseExpected(87 /* FinallyKeyword */);
                node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            }
            return finishNode(node);
        }
        function parseCatchClause() {
            var result = createNode(260 /* CatchClause */);
            parseExpected(74 /* CatchKeyword */);
            if (parseOptional(19 /* OpenParenToken */)) {
                result.variableDeclaration = parseVariableDeclaration();
                parseExpected(20 /* CloseParenToken */);
            }
            else {
                // Keep shape of node to avoid degrading performance.
                result.variableDeclaration = undefined;
            }
            result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
            return finishNode(result);
        }
        function parseDebuggerStatement() {
            var node = createNode(225 /* DebuggerStatement */);
            parseExpected(78 /* DebuggerKeyword */);
            parseSemicolon();
            return finishNode(node);
        }
        function parseExpressionOrLabeledStatement() {
            // Avoiding having to do the lookahead for a labeled statement by just trying to parse
            // out an expression, seeing if it is identifier and then seeing if it is followed by
            // a colon.
            var fullStart = scanner.getStartPos();
            var expression = allowInAnd(parseExpression);
            if (expression.kind === 71 /* Identifier */ && parseOptional(56 /* ColonToken */)) {
                var labeledStatement = createNode(222 /* LabeledStatement */, fullStart);
                labeledStatement.label = expression;
                labeledStatement.statement = parseStatement();
                return addJSDocComment(finishNode(labeledStatement));
            }
            else {
                var expressionStatement = createNode(210 /* ExpressionStatement */, fullStart);
                expressionStatement.expression = expression;
                parseSemicolon();
                return addJSDocComment(finishNode(expressionStatement));
            }
        }
        function nextTokenIsIdentifierOrKeywordOnSameLine() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsClassKeywordOnSameLine() {
            nextToken();
            return token() === 75 /* ClassKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsFunctionKeywordOnSameLine() {
            nextToken();
            return token() === 89 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
            nextToken();
            return (ts.tokenIsIdentifierOrKeyword(token()) || token() === 8 /* NumericLiteral */ || token() === 9 /* StringLiteral */) && !scanner.hasPrecedingLineBreak();
        }
        function isDeclaration() {
            while (true) {
                switch (token()) {
                    case 104 /* VarKeyword */:
                    case 110 /* LetKeyword */:
                    case 76 /* ConstKeyword */:
                    case 89 /* FunctionKeyword */:
                    case 75 /* ClassKeyword */:
                    case 83 /* EnumKeyword */:
                        return true;
                    // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
                    // however, an identifier cannot be followed by another identifier on the same line. This is what we
                    // count on to parse out the respective declarations. For instance, we exploit this to say that
                    //
                    //    namespace n
                    //
                    // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
                    //
                    //    namespace
                    //    n
                    //
                    // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
                    // We need to look one token ahead to see if it permissible to try parsing a declaration.
                    //
                    // *Note*: 'interface' is actually a strict mode reserved word. So while
                    //
                    //   "use strict"
                    //   interface
                    //   I {}
                    //
                    // could be legal, it would add complexity for very little gain.
                    case 109 /* InterfaceKeyword */:
                    case 138 /* TypeKeyword */:
                        return nextTokenIsIdentifierOnSameLine();
                    case 128 /* ModuleKeyword */:
                    case 129 /* NamespaceKeyword */:
                        return nextTokenIsIdentifierOrStringLiteralOnSameLine();
                    case 117 /* AbstractKeyword */:
                    case 120 /* AsyncKeyword */:
                    case 124 /* DeclareKeyword */:
                    case 112 /* PrivateKeyword */:
                    case 113 /* ProtectedKeyword */:
                    case 114 /* PublicKeyword */:
                    case 131 /* ReadonlyKeyword */:
                        nextToken();
                        // ASI takes effect for this modifier.
                        if (scanner.hasPrecedingLineBreak()) {
                            return false;
                        }
                        continue;
                    case 141 /* GlobalKeyword */:
                        nextToken();
                        return token() === 17 /* OpenBraceToken */ || token() === 71 /* Identifier */ || token() === 84 /* ExportKeyword */;
                    case 91 /* ImportKeyword */:
                        nextToken();
                        return token() === 9 /* StringLiteral */ || token() === 39 /* AsteriskToken */ ||
                            token() === 17 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token());
                    case 84 /* ExportKeyword */:
                        nextToken();
                        if (token() === 58 /* EqualsToken */ || token() === 39 /* AsteriskToken */ ||
                            token() === 17 /* OpenBraceToken */ || token() === 79 /* DefaultKeyword */ ||
                            token() === 118 /* AsKeyword */) {
                            return true;
                        }
                        continue;
                    case 115 /* StaticKeyword */:
                        nextToken();
                        continue;
                    default:
                        return false;
                }
            }
        }
        function isStartOfDeclaration() {
            return lookAhead(isDeclaration);
        }
        function isStartOfStatement() {
            switch (token()) {
                case 57 /* AtToken */:
                case 25 /* SemicolonToken */:
                case 17 /* OpenBraceToken */:
                case 104 /* VarKeyword */:
                case 110 /* LetKeyword */:
                case 89 /* FunctionKeyword */:
                case 75 /* ClassKeyword */:
                case 83 /* EnumKeyword */:
                case 90 /* IfKeyword */:
                case 81 /* DoKeyword */:
                case 106 /* WhileKeyword */:
                case 88 /* ForKeyword */:
                case 77 /* ContinueKeyword */:
                case 72 /* BreakKeyword */:
                case 96 /* ReturnKeyword */:
                case 107 /* WithKeyword */:
                case 98 /* SwitchKeyword */:
                case 100 /* ThrowKeyword */:
                case 102 /* TryKeyword */:
                case 78 /* DebuggerKeyword */:
                // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
                // however, we say they are here so that we may gracefully parse them and error later.
                case 74 /* CatchKeyword */:
                case 87 /* FinallyKeyword */:
                    return true;
                case 91 /* ImportKeyword */:
                    return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan);
                case 76 /* ConstKeyword */:
                case 84 /* ExportKeyword */:
                    return isStartOfDeclaration();
                case 120 /* AsyncKeyword */:
                case 124 /* DeclareKeyword */:
                case 109 /* InterfaceKeyword */:
                case 128 /* ModuleKeyword */:
                case 129 /* NamespaceKeyword */:
                case 138 /* TypeKeyword */:
                case 141 /* GlobalKeyword */:
                    // When these don't start a declaration, they're an identifier in an expression statement
                    return true;
                case 114 /* PublicKeyword */:
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 115 /* StaticKeyword */:
                case 131 /* ReadonlyKeyword */:
                    // When these don't start a declaration, they may be the start of a class member if an identifier
                    // immediately follows. Otherwise they're an identifier in an expression statement.
                    return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                default:
                    return isStartOfExpression();
            }
        }
        function nextTokenIsIdentifierOrStartOfDestructuring() {
            nextToken();
            return isIdentifier() || token() === 17 /* OpenBraceToken */ || token() === 21 /* OpenBracketToken */;
        }
        function isLetDeclaration() {
            // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
            // or [.
            return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
        }
        function parseStatement() {
            switch (token()) {
                case 25 /* SemicolonToken */:
                    return parseEmptyStatement();
                case 17 /* OpenBraceToken */:
                    return parseBlock(/*ignoreMissingOpenBrace*/ false);
                case 104 /* VarKeyword */:
                    return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                case 110 /* LetKeyword */:
                    if (isLetDeclaration()) {
                        return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                    }
                    break;
                case 89 /* FunctionKeyword */:
                    return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                case 75 /* ClassKeyword */:
                    return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                case 90 /* IfKeyword */:
                    return parseIfStatement();
                case 81 /* DoKeyword */:
                    return parseDoStatement();
                case 106 /* WhileKeyword */:
                    return parseWhileStatement();
                case 88 /* ForKeyword */:
                    return parseForOrForInOrForOfStatement();
                case 77 /* ContinueKeyword */:
                    return parseBreakOrContinueStatement(217 /* ContinueStatement */);
                case 72 /* BreakKeyword */:
                    return parseBreakOrContinueStatement(218 /* BreakStatement */);
                case 96 /* ReturnKeyword */:
                    return parseReturnStatement();
                case 107 /* WithKeyword */:
                    return parseWithStatement();
                case 98 /* SwitchKeyword */:
                    return parseSwitchStatement();
                case 100 /* ThrowKeyword */:
                    return parseThrowStatement();
                case 102 /* TryKeyword */:
                // Include 'catch' and 'finally' for error recovery.
                case 74 /* CatchKeyword */:
                case 87 /* FinallyKeyword */:
                    return parseTryStatement();
                case 78 /* DebuggerKeyword */:
                    return parseDebuggerStatement();
                case 57 /* AtToken */:
                    return parseDeclaration();
                case 120 /* AsyncKeyword */:
                case 109 /* InterfaceKeyword */:
                case 138 /* TypeKeyword */:
                case 128 /* ModuleKeyword */:
                case 129 /* NamespaceKeyword */:
                case 124 /* DeclareKeyword */:
                case 76 /* ConstKeyword */:
                case 83 /* EnumKeyword */:
                case 84 /* ExportKeyword */:
                case 91 /* ImportKeyword */:
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 114 /* PublicKeyword */:
                case 117 /* AbstractKeyword */:
                case 115 /* StaticKeyword */:
                case 131 /* ReadonlyKeyword */:
                case 141 /* GlobalKeyword */:
                    if (isStartOfDeclaration()) {
                        return parseDeclaration();
                    }
                    break;
            }
            return parseExpressionOrLabeledStatement();
        }
        function parseDeclaration() {
            var fullStart = getNodePos();
            var decorators = parseDecorators();
            var modifiers = parseModifiers();
            switch (token()) {
                case 104 /* VarKeyword */:
                case 110 /* LetKeyword */:
                case 76 /* ConstKeyword */:
                    return parseVariableStatement(fullStart, decorators, modifiers);
                case 89 /* FunctionKeyword */:
                    return parseFunctionDeclaration(fullStart, decorators, modifiers);
                case 75 /* ClassKeyword */:
                    return parseClassDeclaration(fullStart, decorators, modifiers);
                case 109 /* InterfaceKeyword */:
                    return parseInterfaceDeclaration(fullStart, decorators, modifiers);
                case 138 /* TypeKeyword */:
                    return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
                case 83 /* EnumKeyword */:
                    return parseEnumDeclaration(fullStart, decorators, modifiers);
                case 141 /* GlobalKeyword */:
                case 128 /* ModuleKeyword */:
                case 129 /* NamespaceKeyword */:
                    return parseModuleDeclaration(fullStart, decorators, modifiers);
                case 91 /* ImportKeyword */:
                    return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
                case 84 /* ExportKeyword */:
                    nextToken();
                    switch (token()) {
                        case 79 /* DefaultKeyword */:
                        case 58 /* EqualsToken */:
                            return parseExportAssignment(fullStart, decorators, modifiers);
                        case 118 /* AsKeyword */:
                            return parseNamespaceExportDeclaration(fullStart, decorators, modifiers);
                        default:
                            return parseExportDeclaration(fullStart, decorators, modifiers);
                    }
                default:
                    if (decorators || modifiers) {
                        // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
                        // would follow. For recovery and error reporting purposes, return an incomplete declaration.
                        var node = createMissingNode(247 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                        node.pos = fullStart;
                        node.decorators = decorators;
                        node.modifiers = modifiers;
                        return finishNode(node);
                    }
            }
        }
        function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === 9 /* StringLiteral */);
        }
        function parseFunctionBlockOrSemicolon(flags, diagnosticMessage) {
            if (token() !== 17 /* OpenBraceToken */ && canParseSemicolon()) {
                parseSemicolon();
                return;
            }
            return parseFunctionBlock(flags, diagnosticMessage);
        }
        // DECLARATIONS
        function parseArrayBindingElement() {
            if (token() === 26 /* CommaToken */) {
                return createNode(200 /* OmittedExpression */);
            }
            var node = createNode(176 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
            node.name = parseIdentifierOrPattern();
            node.initializer = parseInitializer(/*inParameter*/ false);
            return finishNode(node);
        }
        function parseObjectBindingElement() {
            var node = createNode(176 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            if (tokenIsIdentifier && token() !== 56 /* ColonToken */) {
                node.name = propertyName;
            }
            else {
                parseExpected(56 /* ColonToken */);
                node.propertyName = propertyName;
                node.name = parseIdentifierOrPattern();
            }
            node.initializer = parseInitializer(/*inParameter*/ false);
            return finishNode(node);
        }
        function parseObjectBindingPattern() {
            var node = createNode(174 /* ObjectBindingPattern */);
            parseExpected(17 /* OpenBraceToken */);
            node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
            parseExpected(18 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseArrayBindingPattern() {
            var node = createNode(175 /* ArrayBindingPattern */);
            parseExpected(21 /* OpenBracketToken */);
            node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
            parseExpected(22 /* CloseBracketToken */);
            return finishNode(node);
        }
        function isIdentifierOrPattern() {
            return token() === 17 /* OpenBraceToken */ || token() === 21 /* OpenBracketToken */ || isIdentifier();
        }
        function parseIdentifierOrPattern() {
            if (token() === 21 /* OpenBracketToken */) {
                return parseArrayBindingPattern();
            }
            if (token() === 17 /* OpenBraceToken */) {
                return parseObjectBindingPattern();
            }
            return parseIdentifier();
        }
        function parseVariableDeclaration() {
            var node = createNode(226 /* VariableDeclaration */);
            node.name = parseIdentifierOrPattern();
            node.type = parseTypeAnnotation();
            if (!isInOrOfKeyword(token())) {
                node.initializer = parseNonParameterInitializer();
            }
            return finishNode(node);
        }
        function parseVariableDeclarationList(inForStatementInitializer) {
            var node = createNode(227 /* VariableDeclarationList */);
            switch (token()) {
                case 104 /* VarKeyword */:
                    break;
                case 110 /* LetKeyword */:
                    node.flags |= 1 /* Let */;
                    break;
                case 76 /* ConstKeyword */:
                    node.flags |= 2 /* Const */;
                    break;
                default:
                    ts.Debug.fail();
            }
            nextToken();
            // The user may have written the following:
            //
            //    for (let of X) { }
            //
            // In this case, we want to parse an empty declaration list, and then parse 'of'
            // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
            // So we need to look ahead to determine if 'of' should be treated as a keyword in
            // this context.
            // The checker will then give an error that there is an empty declaration list.
            if (token() === 142 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
                node.declarations = createMissingList();
            }
            else {
                var savedDisallowIn = inDisallowInContext();
                setDisallowInContext(inForStatementInitializer);
                node.declarations = parseDelimitedList(8 /* VariableDeclarations */, parseVariableDeclaration);
                setDisallowInContext(savedDisallowIn);
            }
            return finishNode(node);
        }
        function canFollowContextualOfKeyword() {
            return nextTokenIsIdentifier() && nextToken() === 20 /* CloseParenToken */;
        }
        function parseVariableStatement(fullStart, decorators, modifiers) {
            var node = createNode(208 /* VariableStatement */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
            parseSemicolon();
            return addJSDocComment(finishNode(node));
        }
        function parseFunctionDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(228 /* FunctionDeclaration */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            parseExpected(89 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
            node.name = ts.hasModifier(node, 512 /* Default */) ? parseOptionalIdentifier() : parseIdentifier();
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(56 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected);
            return addJSDocComment(finishNode(node));
        }
        function parseConstructorDeclaration(pos, decorators, modifiers) {
            var node = createNode(152 /* Constructor */, pos);
            node.decorators = decorators;
            node.modifiers = modifiers;
            parseExpected(123 /* ConstructorKeyword */);
            fillSignature(56 /* ColonToken */, 0 /* None */, node);
            node.body = parseFunctionBlockOrSemicolon(0 /* None */, ts.Diagnostics.or_expected);
            return addJSDocComment(finishNode(node));
        }
        function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
            var method = createNode(151 /* MethodDeclaration */, fullStart);
            method.decorators = decorators;
            method.modifiers = modifiers;
            method.asteriskToken = asteriskToken;
            method.name = name;
            method.questionToken = questionToken;
            var isGenerator = asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = ts.hasModifier(method, 256 /* Async */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(56 /* ColonToken */, isGenerator | isAsync, method);
            method.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage);
            return addJSDocComment(finishNode(method));
        }
        function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
            var property = createNode(149 /* PropertyDeclaration */, fullStart);
            property.decorators = decorators;
            property.modifiers = modifiers;
            property.name = name;
            property.questionToken = questionToken;
            property.type = parseTypeAnnotation();
            // For instance properties specifically, since they are evaluated inside the constructor,
            // we do *not * want to parse yield expressions, so we specifically turn the yield context
            // off. The grammar would look something like this:
            //
            //    MemberVariableDeclaration[Yield]:
            //        AccessibilityModifier_opt   PropertyName   TypeAnnotation_opt   Initializer_opt[In];
            //        AccessibilityModifier_opt  static_opt  PropertyName   TypeAnnotation_opt   Initializer_opt[In, ?Yield];
            //
            // The checker may still error in the static case to explicitly disallow the yield expression.
            property.initializer = ts.hasModifier(property, 32 /* Static */)
                ? allowInAnd(parseNonParameterInitializer)
                : doOutsideOfContext(4096 /* YieldContext */ | 2048 /* DisallowInContext */, parseNonParameterInitializer);
            parseSemicolon();
            return addJSDocComment(finishNode(property));
        }
        function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
            var asteriskToken = parseOptionalToken(39 /* AsteriskToken */);
            var name = parsePropertyName();
            // Note: this is not legal as per the grammar.  But we allow it in the parser and
            // report an error in the grammar checker.
            var questionToken = parseOptionalToken(55 /* QuestionToken */);
            if (asteriskToken || token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) {
                return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
            }
            else {
                return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
            }
        }
        function parseNonParameterInitializer() {
            return parseInitializer(/*inParameter*/ false);
        }
        function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
            var node = createNode(kind, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            node.name = parsePropertyName();
            fillSignature(56 /* ColonToken */, 0 /* None */, node);
            node.body = parseFunctionBlockOrSemicolon(0 /* None */);
            return addJSDocComment(finishNode(node));
        }
        function isClassMemberModifier(idToken) {
            switch (idToken) {
                case 114 /* PublicKeyword */:
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 115 /* StaticKeyword */:
                case 131 /* ReadonlyKeyword */:
                    return true;
                default:
                    return false;
            }
        }
        function isClassMemberStart() {
            var idToken;
            if (token() === 57 /* AtToken */) {
                return true;
            }
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
            while (ts.isModifierKind(token())) {
                idToken = token();
                // If the idToken is a class modifier (protected, private, public, and static), it is
                // certain that we are starting to parse class member. This allows better error recovery
                // Example:
                //      public foo() ...     // true
                //      public @dec blah ... // true; we will then report an error later
                //      export public ...    // true; we will then report an error later
                if (isClassMemberModifier(idToken)) {
                    return true;
                }
                nextToken();
            }
            if (token() === 39 /* AsteriskToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers.
            // This can either be an identifier or the 'get' or 'set' keywords.
            if (isLiteralPropertyName()) {
                idToken = token();
                nextToken();
            }
            // Index signatures and computed properties are class members; we can parse.
            if (token() === 21 /* OpenBracketToken */) {
                return true;
            }
            // If we were able to get any potential identifier...
            if (idToken !== undefined) {
                // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
                if (!ts.isKeyword(idToken) || idToken === 135 /* SetKeyword */ || idToken === 125 /* GetKeyword */) {
                    return true;
                }
                // If it *is* a keyword, but not an accessor, check a little farther along
                // to see if it should actually be parsed as a class member.
                switch (token()) {
                    case 19 /* OpenParenToken */: // Method declaration
                    case 27 /* LessThanToken */: // Generic Method declaration
                    case 56 /* ColonToken */: // Type Annotation for declaration
                    case 58 /* EqualsToken */: // Initializer for declaration
                    case 55 /* QuestionToken */:// Not valid, but permitted so that it gets caught later on.
                        return true;
                    default:
                        // Covers
                        //  - Semicolons     (declaration termination)
                        //  - Closing braces (end-of-class, must be declaration)
                        //  - End-of-files   (not valid, but permitted so that it gets caught later on)
                        //  - Line-breaks    (enabling *automatic semicolon insertion*)
                        return canParseSemicolon();
                }
            }
            return false;
        }
        function parseDecorators() {
            var list;
            var listPos = getNodePos();
            while (true) {
                var decoratorStart = getNodePos();
                if (!parseOptional(57 /* AtToken */)) {
                    break;
                }
                var decorator = createNode(147 /* Decorator */, decoratorStart);
                decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
                finishNode(decorator);
                (list || (list = [])).push(decorator);
            }
            return list && createNodeArray(list, listPos);
        }
        /*
         * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
         * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
         * and turns it into a standalone declaration), then it is better to parse it and report an error later.
         *
         * In such situations, 'permitInvalidConstAsModifier' should be set to true.
         */
        function parseModifiers(permitInvalidConstAsModifier) {
            var list;
            var listPos = getNodePos();
            while (true) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                if (token() === 76 /* ConstKeyword */ && permitInvalidConstAsModifier) {
                    // We need to ensure that any subsequent modifiers appear on the same line
                    // so that when 'const' is a standalone declaration, we don't issue an error.
                    if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
                        break;
                    }
                }
                else {
                    if (!parseAnyContextualModifier()) {
                        break;
                    }
                }
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                (list || (list = [])).push(modifier);
            }
            return list && createNodeArray(list, listPos);
        }
        function parseModifiersForArrowFunction() {
            var modifiers;
            if (token() === 120 /* AsyncKeyword */) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                nextToken();
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                modifiers = createNodeArray([modifier], modifierStart);
            }
            return modifiers;
        }
        function parseClassElement() {
            if (token() === 25 /* SemicolonToken */) {
                var result = createNode(206 /* SemicolonClassElement */);
                nextToken();
                return finishNode(result);
            }
            var fullStart = getNodePos();
            var decorators = parseDecorators();
            var modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true);
            var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
            if (accessor) {
                return accessor;
            }
            if (token() === 123 /* ConstructorKeyword */) {
                return parseConstructorDeclaration(fullStart, decorators, modifiers);
            }
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
            }
            // It is very important that we check this *after* checking indexers because
            // the [ token can start an index signature or a computed property name
            if (ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 9 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */ ||
                token() === 39 /* AsteriskToken */ ||
                token() === 21 /* OpenBracketToken */) {
                return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
            }
            if (decorators || modifiers) {
                // treat this as a property declaration with a missing name.
                var name = createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                return parsePropertyDeclaration(fullStart, decorators, modifiers, name, /*questionToken*/ undefined);
            }
            // 'isClassMemberStart' should have hinted not to attempt parsing.
            ts.Debug.fail("Should not have attempted to parse class member declaration.");
        }
        function parseClassExpression() {
            return parseClassDeclarationOrExpression(
            /*fullStart*/ scanner.getStartPos(), 
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 199 /* ClassExpression */);
        }
        function parseClassDeclaration(fullStart, decorators, modifiers) {
            return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 229 /* ClassDeclaration */);
        }
        function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
            var node = createNode(kind, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            parseExpected(75 /* ClassKeyword */);
            node.name = parseNameOfClassDeclarationOrExpression();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            if (parseExpected(17 /* OpenBraceToken */)) {
                // ClassTail[Yield,Await] : (Modified) See 14.5
                //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
                node.members = parseClassMembers();
                parseExpected(18 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return addJSDocComment(finishNode(node));
        }
        function parseNameOfClassDeclarationOrExpression() {
            // implements is a future reserved word so
            // 'class implements' might mean either
            // - class expression with omitted name, 'implements' starts heritage clause
            // - class with name 'implements'
            // 'isImplementsClause' helps to disambiguate between these two cases
            return isIdentifier() && !isImplementsClause()
                ? parseIdentifier()
                : undefined;
        }
        function isImplementsClause() {
            return token() === 108 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
        }
        function parseHeritageClauses() {
            // ClassTail[Yield,Await] : (Modified) See 14.5
            //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
            if (isHeritageClause()) {
                return parseList(21 /* HeritageClauses */, parseHeritageClause);
            }
            return undefined;
        }
        function parseHeritageClause() {
            var tok = token();
            if (tok === 85 /* ExtendsKeyword */ || tok === 108 /* ImplementsKeyword */) {
                var node = createNode(259 /* HeritageClause */);
                node.token = tok;
                nextToken();
                node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
                return finishNode(node);
            }
            return undefined;
        }
        function parseExpressionWithTypeArguments() {
            var node = createNode(201 /* ExpressionWithTypeArguments */);
            node.expression = parseLeftHandSideExpressionOrHigher();
            node.typeArguments = tryParseTypeArguments();
            return finishNode(node);
        }
        function tryParseTypeArguments() {
            return token() === 27 /* LessThanToken */
                ? parseBracketedList(19 /* TypeArguments */, parseType, 27 /* LessThanToken */, 29 /* GreaterThanToken */)
                : undefined;
        }
        function isHeritageClause() {
            return token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */;
        }
        function parseClassMembers() {
            return parseList(5 /* ClassMembers */, parseClassElement);
        }
        function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(230 /* InterfaceDeclaration */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            parseExpected(109 /* InterfaceKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            node.members = parseObjectTypeMembers();
            return addJSDocComment(finishNode(node));
        }
        function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(231 /* TypeAliasDeclaration */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            parseExpected(138 /* TypeKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            parseExpected(58 /* EqualsToken */);
            node.type = parseType();
            parseSemicolon();
            return addJSDocComment(finishNode(node));
        }
        // In an ambient declaration, the grammar only allows integer literals as initializers.
        // In a non-ambient declaration, the grammar allows uninitialized members only in a
        // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
        // or any time an integer literal initializer is encountered.
        function parseEnumMember() {
            var node = createNode(264 /* EnumMember */, scanner.getStartPos());
            node.name = parsePropertyName();
            node.initializer = allowInAnd(parseNonParameterInitializer);
            return addJSDocComment(finishNode(node));
        }
        function parseEnumDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(232 /* EnumDeclaration */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            parseExpected(83 /* EnumKeyword */);
            node.name = parseIdentifier();
            if (parseExpected(17 /* OpenBraceToken */)) {
                node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
                parseExpected(18 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return addJSDocComment(finishNode(node));
        }
        function parseModuleBlock() {
            var node = createNode(234 /* ModuleBlock */, scanner.getStartPos());
            if (parseExpected(17 /* OpenBraceToken */)) {
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(18 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
            var node = createNode(233 /* ModuleDeclaration */, fullStart);
            // If we are parsing a dotted namespace name, we want to
            // propagate the 'Namespace' flag across the names if set.
            var namespaceFlag = flags & 16 /* Namespace */;
            node.decorators = decorators;
            node.modifiers = modifiers;
            node.flags |= flags;
            node.name = parseIdentifier();
            node.body = parseOptional(23 /* DotToken */)
                ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 4 /* NestedNamespace */ | namespaceFlag)
                : parseModuleBlock();
            return addJSDocComment(finishNode(node));
        }
        function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(233 /* ModuleDeclaration */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            if (token() === 141 /* GlobalKeyword */) {
                // parse 'global' as name of global scope augmentation
                node.name = parseIdentifier();
                node.flags |= 512 /* GlobalAugmentation */;
            }
            else {
                node.name = parseLiteralNode();
                node.name.text = internIdentifier(node.name.text);
            }
            if (token() === 17 /* OpenBraceToken */) {
                node.body = parseModuleBlock();
            }
            else {
                parseSemicolon();
            }
            return finishNode(node);
        }
        function parseModuleDeclaration(fullStart, decorators, modifiers) {
            var flags = 0;
            if (token() === 141 /* GlobalKeyword */) {
                // global augmentation
                return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
            }
            else if (parseOptional(129 /* NamespaceKeyword */)) {
                flags |= 16 /* Namespace */;
            }
            else {
                parseExpected(128 /* ModuleKeyword */);
                if (token() === 9 /* StringLiteral */) {
                    return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
                }
            }
            return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
        }
        function isExternalModuleReference() {
            return token() === 132 /* RequireKeyword */ &&
                lookAhead(nextTokenIsOpenParen);
        }
        function nextTokenIsOpenParen() {
            return nextToken() === 19 /* OpenParenToken */;
        }
        function nextTokenIsSlash() {
            return nextToken() === 41 /* SlashToken */;
        }
        function parseNamespaceExportDeclaration(fullStart, decorators, modifiers) {
            var exportDeclaration = createNode(236 /* NamespaceExportDeclaration */, fullStart);
            exportDeclaration.decorators = decorators;
            exportDeclaration.modifiers = modifiers;
            parseExpected(118 /* AsKeyword */);
            parseExpected(129 /* NamespaceKeyword */);
            exportDeclaration.name = parseIdentifier();
            parseSemicolon();
            return finishNode(exportDeclaration);
        }
        function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
            parseExpected(91 /* ImportKeyword */);
            var afterImportPos = scanner.getStartPos();
            var identifier;
            if (isIdentifier()) {
                identifier = parseIdentifier();
                if (token() !== 26 /* CommaToken */ && token() !== 140 /* FromKeyword */) {
                    return parseImportEqualsDeclaration(fullStart, decorators, modifiers, identifier);
                }
            }
            // Import statement
            var importDeclaration = createNode(238 /* ImportDeclaration */, fullStart);
            importDeclaration.decorators = decorators;
            importDeclaration.modifiers = modifiers;
            // ImportDeclaration:
            //  import ImportClause from ModuleSpecifier ;
            //  import ModuleSpecifier;
            if (identifier || // import id
                token() === 39 /* AsteriskToken */ || // import *
                token() === 17 /* OpenBraceToken */) {
                importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
                parseExpected(140 /* FromKeyword */);
            }
            importDeclaration.moduleSpecifier = parseModuleSpecifier();
            parseSemicolon();
            return finishNode(importDeclaration);
        }
        function parseImportEqualsDeclaration(fullStart, decorators, modifiers, identifier) {
            var importEqualsDeclaration = createNode(237 /* ImportEqualsDeclaration */, fullStart);
            importEqualsDeclaration.decorators = decorators;
            importEqualsDeclaration.modifiers = modifiers;
            importEqualsDeclaration.name = identifier;
            parseExpected(58 /* EqualsToken */);
            importEqualsDeclaration.moduleReference = parseModuleReference();
            parseSemicolon();
            return addJSDocComment(finishNode(importEqualsDeclaration));
        }
        function parseImportClause(identifier, fullStart) {
            // ImportClause:
            //  ImportedDefaultBinding
            //  NameSpaceImport
            //  NamedImports
            //  ImportedDefaultBinding, NameSpaceImport
            //  ImportedDefaultBinding, NamedImports
            var importClause = createNode(239 /* ImportClause */, fullStart);
            if (identifier) {
                // ImportedDefaultBinding:
                //  ImportedBinding
                importClause.name = identifier;
            }
            // If there was no default import or if there is comma token after default import
            // parse namespace or named imports
            if (!importClause.name ||
                parseOptional(26 /* CommaToken */)) {
                importClause.namedBindings = token() === 39 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(241 /* NamedImports */);
            }
            return finishNode(importClause);
        }
        function parseModuleReference() {
            return isExternalModuleReference()
                ? parseExternalModuleReference()
                : parseEntityName(/*allowReservedWords*/ false);
        }
        function parseExternalModuleReference() {
            var node = createNode(248 /* ExternalModuleReference */);
            parseExpected(132 /* RequireKeyword */);
            parseExpected(19 /* OpenParenToken */);
            node.expression = parseModuleSpecifier();
            parseExpected(20 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseModuleSpecifier() {
            if (token() === 9 /* StringLiteral */) {
                var result = parseLiteralNode();
                result.text = internIdentifier(result.text);
                return result;
            }
            else {
                // We allow arbitrary expressions here, even though the grammar only allows string
                // literals.  We check to ensure that it is only a string literal later in the grammar
                // check pass.
                return parseExpression();
            }
        }
        function parseNamespaceImport() {
            // NameSpaceImport:
            //  * as ImportedBinding
            var namespaceImport = createNode(240 /* NamespaceImport */);
            parseExpected(39 /* AsteriskToken */);
            parseExpected(118 /* AsKeyword */);
            namespaceImport.name = parseIdentifier();
            return finishNode(namespaceImport);
        }
        function parseNamedImportsOrExports(kind) {
            var node = createNode(kind);
            // NamedImports:
            //  { }
            //  { ImportsList }
            //  { ImportsList, }
            // ImportsList:
            //  ImportSpecifier
            //  ImportsList, ImportSpecifier
            node.elements = parseBracketedList(22 /* ImportOrExportSpecifiers */, kind === 241 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 17 /* OpenBraceToken */, 18 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseExportSpecifier() {
            return parseImportOrExportSpecifier(246 /* ExportSpecifier */);
        }
        function parseImportSpecifier() {
            return parseImportOrExportSpecifier(242 /* ImportSpecifier */);
        }
        function parseImportOrExportSpecifier(kind) {
            var node = createNode(kind);
            // ImportSpecifier:
            //   BindingIdentifier
            //   IdentifierName as BindingIdentifier
            // ExportSpecifier:
            //   IdentifierName
            //   IdentifierName as IdentifierName
            var checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
            var checkIdentifierStart = scanner.getTokenPos();
            var checkIdentifierEnd = scanner.getTextPos();
            var identifierName = parseIdentifierName();
            if (token() === 118 /* AsKeyword */) {
                node.propertyName = identifierName;
                parseExpected(118 /* AsKeyword */);
                checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
                checkIdentifierStart = scanner.getTokenPos();
                checkIdentifierEnd = scanner.getTextPos();
                node.name = parseIdentifierName();
            }
            else {
                node.name = identifierName;
            }
            if (kind === 242 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
                // Report error identifier expected
                parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
            }
            return finishNode(node);
        }
        function parseExportDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(244 /* ExportDeclaration */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            if (parseOptional(39 /* AsteriskToken */)) {
                parseExpected(140 /* FromKeyword */);
                node.moduleSpecifier = parseModuleSpecifier();
            }
            else {
                node.exportClause = parseNamedImportsOrExports(245 /* NamedExports */);
                // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
                // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
                // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
                if (token() === 140 /* FromKeyword */ || (token() === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
                    parseExpected(140 /* FromKeyword */);
                    node.moduleSpecifier = parseModuleSpecifier();
                }
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseExportAssignment(fullStart, decorators, modifiers) {
            var node = createNode(243 /* ExportAssignment */, fullStart);
            node.decorators = decorators;
            node.modifiers = modifiers;
            if (parseOptional(58 /* EqualsToken */)) {
                node.isExportEquals = true;
            }
            else {
                parseExpected(79 /* DefaultKeyword */);
            }
            node.expression = parseAssignmentExpressionOrHigher();
            parseSemicolon();
            return finishNode(node);
        }
        function processReferenceComments(sourceFile) {
            var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText);
            var referencedFiles = [];
            var typeReferenceDirectives = [];
            var amdDependencies = [];
            var amdModuleName;
            var checkJsDirective = undefined;
            // Keep scanning all the leading trivia in the file until we get to something that
            // isn't trivia.  Any single line comment will be analyzed to see if it is a
            // reference comment.
            while (true) {
                var kind = triviaScanner.scan();
                if (kind !== 2 /* SingleLineCommentTrivia */) {
                    if (ts.isTrivia(kind)) {
                        continue;
                    }
                    else {
                        break;
                    }
                }
                var range = {
                    kind: triviaScanner.getToken(),
                    pos: triviaScanner.getTokenPos(),
                    end: triviaScanner.getTextPos(),
                };
                var comment = sourceText.substring(range.pos, range.end);
                var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
                if (referencePathMatchResult) {
                    var fileReference = referencePathMatchResult.fileReference;
                    sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
                    var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
                    if (fileReference) {
                        if (referencePathMatchResult.isTypeReferenceDirective) {
                            typeReferenceDirectives.push(fileReference);
                        }
                        else {
                            referencedFiles.push(fileReference);
                        }
                    }
                    if (diagnosticMessage) {
                        parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
                    }
                }
                else {
                    var amdModuleNameRegEx = /^\/\/\/\s*<amd-module\s+name\s*=\s*('|")(.+?)\1/gim;
                    var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment);
                    if (amdModuleNameMatchResult) {
                        if (amdModuleName) {
                            parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments));
                        }
                        amdModuleName = amdModuleNameMatchResult[2];
                    }
                    var amdDependencyRegEx = /^\/\/\/\s*<amd-dependency\s/gim;
                    var pathRegex = /\spath\s*=\s*('|")(.+?)\1/gim;
                    var nameRegex = /\sname\s*=\s*('|")(.+?)\1/gim;
                    var amdDependencyMatchResult = amdDependencyRegEx.exec(comment);
                    if (amdDependencyMatchResult) {
                        var pathMatchResult = pathRegex.exec(comment);
                        var nameMatchResult = nameRegex.exec(comment);
                        if (pathMatchResult) {
                            var amdDependency = { path: pathMatchResult[2], name: nameMatchResult ? nameMatchResult[2] : undefined };
                            amdDependencies.push(amdDependency);
                        }
                    }
                    var checkJsDirectiveRegEx = /^\/\/\/?\s*(@ts-check|@ts-nocheck)\s*$/gim;
                    var checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment);
                    if (checkJsDirectiveMatchResult) {
                        checkJsDirective = {
                            enabled: ts.compareStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true) === 0 /* EqualTo */,
                            end: range.end,
                            pos: range.pos
                        };
                    }
                }
            }
            sourceFile.referencedFiles = referencedFiles;
            sourceFile.typeReferenceDirectives = typeReferenceDirectives;
            sourceFile.amdDependencies = amdDependencies;
            sourceFile.moduleName = amdModuleName;
            sourceFile.checkJsDirective = checkJsDirective;
        }
        function setExternalModuleIndicator(sourceFile) {
            sourceFile.externalModuleIndicator = ts.forEach(sourceFile.statements, function (node) {
                return ts.hasModifier(node, 1 /* Export */)
                    || node.kind === 237 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 248 /* ExternalModuleReference */
                    || node.kind === 238 /* ImportDeclaration */
                    || node.kind === 243 /* ExportAssignment */
                    || node.kind === 244 /* ExportDeclaration */
                    ? node
                    : undefined;
            });
        }
        var ParsingContext;
        (function (ParsingContext) {
            ParsingContext[ParsingContext["SourceElements"] = 0] = "SourceElements";
            ParsingContext[ParsingContext["BlockStatements"] = 1] = "BlockStatements";
            ParsingContext[ParsingContext["SwitchClauses"] = 2] = "SwitchClauses";
            ParsingContext[ParsingContext["SwitchClauseStatements"] = 3] = "SwitchClauseStatements";
            ParsingContext[ParsingContext["TypeMembers"] = 4] = "TypeMembers";
            ParsingContext[ParsingContext["ClassMembers"] = 5] = "ClassMembers";
            ParsingContext[ParsingContext["EnumMembers"] = 6] = "EnumMembers";
            ParsingContext[ParsingContext["HeritageClauseElement"] = 7] = "HeritageClauseElement";
            ParsingContext[ParsingContext["VariableDeclarations"] = 8] = "VariableDeclarations";
            ParsingContext[ParsingContext["ObjectBindingElements"] = 9] = "ObjectBindingElements";
            ParsingContext[ParsingContext["ArrayBindingElements"] = 10] = "ArrayBindingElements";
            ParsingContext[ParsingContext["ArgumentExpressions"] = 11] = "ArgumentExpressions";
            ParsingContext[ParsingContext["ObjectLiteralMembers"] = 12] = "ObjectLiteralMembers";
            ParsingContext[ParsingContext["JsxAttributes"] = 13] = "JsxAttributes";
            ParsingContext[ParsingContext["JsxChildren"] = 14] = "JsxChildren";
            ParsingContext[ParsingContext["ArrayLiteralMembers"] = 15] = "ArrayLiteralMembers";
            ParsingContext[ParsingContext["Parameters"] = 16] = "Parameters";
            ParsingContext[ParsingContext["RestProperties"] = 17] = "RestProperties";
            ParsingContext[ParsingContext["TypeParameters"] = 18] = "TypeParameters";
            ParsingContext[ParsingContext["TypeArguments"] = 19] = "TypeArguments";
            ParsingContext[ParsingContext["TupleElementTypes"] = 20] = "TupleElementTypes";
            ParsingContext[ParsingContext["HeritageClauses"] = 21] = "HeritageClauses";
            ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 22] = "ImportOrExportSpecifiers";
            ParsingContext[ParsingContext["Count"] = 23] = "Count"; // Number of parsing contexts
        })(ParsingContext || (ParsingContext = {}));
        var Tristate;
        (function (Tristate) {
            Tristate[Tristate["False"] = 0] = "False";
            Tristate[Tristate["True"] = 1] = "True";
            Tristate[Tristate["Unknown"] = 2] = "Unknown";
        })(Tristate || (Tristate = {}));
        var JSDocParser;
        (function (JSDocParser) {
            function parseJSDocTypeExpressionForTests(content, start, length) {
                initializeState(content, 5 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = createSourceFile("file.js", 5 /* Latest */, 1 /* JS */);
                scanner.setText(content, start, length);
                currentToken = scanner.scan();
                var jsDocTypeExpression = parseJSDocTypeExpression();
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
            function parseJSDocTypeExpression(requireBraces) {
                var result = createNode(267 /* JSDocTypeExpression */, scanner.getTokenPos());
                if (!parseExpected(17 /* OpenBraceToken */) && requireBraces) {
                    return undefined;
                }
                result.type = doInsideOfContext(1048576 /* JSDoc */, parseType);
                parseExpected(18 /* CloseBraceToken */);
                fixupParentReferences(result);
                return finishNode(result);
            }
            JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
            function parseIsolatedJSDocComment(content, start, length) {
                initializeState(content, 5 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = { languageVariant: 0 /* Standard */, text: content }; // tslint:disable-line no-object-literal-type-assertion
                var jsDoc = parseJSDocCommentWorker(start, length);
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDoc ? { jsDoc: jsDoc, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
            function parseJSDocComment(parent, start, length) {
                var saveToken = currentToken;
                var saveParseDiagnosticsLength = parseDiagnostics.length;
                var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
                var comment = parseJSDocCommentWorker(start, length);
                if (comment) {
                    comment.parent = parent;
                }
                if (ts.isInJavaScriptFile(parent)) {
                    if (!sourceFile.jsDocDiagnostics) {
                        sourceFile.jsDocDiagnostics = [];
                    }
                    (_a = sourceFile.jsDocDiagnostics).push.apply(_a, parseDiagnostics);
                }
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
                return comment;
                var _a;
            }
            JSDocParser.parseJSDocComment = parseJSDocComment;
            var JSDocState;
            (function (JSDocState) {
                JSDocState[JSDocState["BeginningOfLine"] = 0] = "BeginningOfLine";
                JSDocState[JSDocState["SawAsterisk"] = 1] = "SawAsterisk";
                JSDocState[JSDocState["SavingComments"] = 2] = "SavingComments";
            })(JSDocState || (JSDocState = {}));
            var PropertyLikeParse;
            (function (PropertyLikeParse) {
                PropertyLikeParse[PropertyLikeParse["Property"] = 0] = "Property";
                PropertyLikeParse[PropertyLikeParse["Parameter"] = 1] = "Parameter";
            })(PropertyLikeParse || (PropertyLikeParse = {}));
            function parseJSDocCommentWorker(start, length) {
                var content = sourceText;
                start = start || 0;
                var end = length === undefined ? content.length : start + length;
                length = end - start;
                ts.Debug.assert(start >= 0);
                ts.Debug.assert(start <= end);
                ts.Debug.assert(end <= content.length);
                var tags;
                var tagsPos;
                var tagsEnd;
                var comments = [];
                var result;
                // Check for /** (JSDoc opening part)
                if (!isJsDocStart(content, start)) {
                    return result;
                }
                // + 3 for leading /**, - 5 in total for /** */
                scanner.scanRange(start + 3, length - 5, function () {
                    // Initially we can parse out a tag.  We also have seen a starting asterisk.
                    // This is so that /** * @type */ doesn't parse.
                    var advanceToken = true;
                    var state = 1 /* SawAsterisk */;
                    var margin = undefined;
                    // + 4 for leading '/** '
                    var indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    nextJSDocToken();
                    while (token() === 5 /* WhitespaceTrivia */) {
                        nextJSDocToken();
                    }
                    if (token() === 4 /* NewLineTrivia */) {
                        state = 0 /* BeginningOfLine */;
                        indent = 0;
                        nextJSDocToken();
                    }
                    while (token() !== 1 /* EndOfFileToken */) {
                        switch (token()) {
                            case 57 /* AtToken */:
                                if (state === 0 /* BeginningOfLine */ || state === 1 /* SawAsterisk */) {
                                    removeTrailingNewlines(comments);
                                    parseTag(indent);
                                    // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag.
                                    // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning
                                    // for malformed examples like `/** @param {string} x @returns {number} the length */`
                                    state = 0 /* BeginningOfLine */;
                                    advanceToken = false;
                                    margin = undefined;
                                    indent++;
                                }
                                else {
                                    pushComment(scanner.getTokenText());
                                }
                                break;
                            case 4 /* NewLineTrivia */:
                                comments.push(scanner.getTokenText());
                                state = 0 /* BeginningOfLine */;
                                indent = 0;
                                break;
                            case 39 /* AsteriskToken */:
                                var asterisk = scanner.getTokenText();
                                if (state === 1 /* SawAsterisk */ || state === 2 /* SavingComments */) {
                                    // If we've already seen an asterisk, then we can no longer parse a tag on this line
                                    state = 2 /* SavingComments */;
                                    pushComment(asterisk);
                                }
                                else {
                                    // Ignore the first asterisk on a line
                                    state = 1 /* SawAsterisk */;
                                    indent += asterisk.length;
                                }
                                break;
                            case 71 /* Identifier */:
                                // Anything else is doc comment text. We just save it. Because it
                                // wasn't a tag, we can no longer parse a tag on this line until we hit the next
                                // line break.
                                pushComment(scanner.getTokenText());
                                state = 2 /* SavingComments */;
                                break;
                            case 5 /* WhitespaceTrivia */:
                                // only collect whitespace if we're already saving comments or have just crossed the comment indent margin
                                var whitespace = scanner.getTokenText();
                                if (state === 2 /* SavingComments */) {
                                    comments.push(whitespace);
                                }
                                else if (margin !== undefined && indent + whitespace.length > margin) {
                                    comments.push(whitespace.slice(margin - indent - 1));
                                }
                                indent += whitespace.length;
                                break;
                            case 1 /* EndOfFileToken */:
                                break;
                            default:
                                // anything other than whitespace or asterisk at the beginning of the line starts the comment text
                                state = 2 /* SavingComments */;
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        if (advanceToken) {
                            nextJSDocToken();
                        }
                        else {
                            advanceToken = true;
                        }
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingNewlines(comments);
                    result = createJSDocComment();
                });
                return result;
                function removeLeadingNewlines(comments) {
                    while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) {
                        comments.shift();
                    }
                }
                function removeTrailingNewlines(comments) {
                    while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) {
                        comments.pop();
                    }
                }
                function isJsDocStart(content, start) {
                    return content.charCodeAt(start) === 47 /* slash */ &&
                        content.charCodeAt(start + 1) === 42 /* asterisk */ &&
                        content.charCodeAt(start + 2) === 42 /* asterisk */ &&
                        content.charCodeAt(start + 3) !== 42 /* asterisk */;
                }
                function createJSDocComment() {
                    var result = createNode(275 /* JSDocComment */, start);
                    result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
                    result.comment = comments.length ? comments.join("") : undefined;
                    return finishNode(result, end);
                }
                function skipWhitespace() {
                    while (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        nextJSDocToken();
                    }
                }
                function parseTag(indent) {
                    ts.Debug.assert(token() === 57 /* AtToken */);
                    var atToken = createNode(57 /* AtToken */, scanner.getTokenPos());
                    atToken.end = scanner.getTextPos();
                    nextJSDocToken();
                    var tagName = parseJSDocIdentifierName();
                    skipWhitespace();
                    if (!tagName) {
                        return;
                    }
                    var tag;
                    if (tagName) {
                        switch (tagName.escapedText) {
                            case "augments":
                            case "extends":
                                tag = parseAugmentsTag(atToken, tagName);
                                break;
                            case "class":
                            case "constructor":
                                tag = parseClassTag(atToken, tagName);
                                break;
                            case "arg":
                            case "argument":
                            case "param":
                                tag = parseParameterOrPropertyTag(atToken, tagName, 1 /* Parameter */);
                                break;
                            case "return":
                            case "returns":
                                tag = parseReturnTag(atToken, tagName);
                                break;
                            case "template":
                                tag = parseTemplateTag(atToken, tagName);
                                break;
                            case "type":
                                tag = parseTypeTag(atToken, tagName);
                                break;
                            case "typedef":
                                tag = parseTypedefTag(atToken, tagName);
                                break;
                            default:
                                tag = parseUnknownTag(atToken, tagName);
                                break;
                        }
                    }
                    else {
                        tag = parseUnknownTag(atToken, tagName);
                    }
                    if (!tag) {
                        // a badly malformed tag should not be added to the list of tags
                        return;
                    }
                    addTag(tag, parseTagComments(indent + tag.end - tag.pos));
                }
                function parseTagComments(indent) {
                    var comments = [];
                    var state = 0 /* BeginningOfLine */;
                    var margin;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    while (token() !== 57 /* AtToken */ && token() !== 1 /* EndOfFileToken */) {
                        switch (token()) {
                            case 4 /* NewLineTrivia */:
                                if (state >= 1 /* SawAsterisk */) {
                                    state = 0 /* BeginningOfLine */;
                                    comments.push(scanner.getTokenText());
                                }
                                indent = 0;
                                break;
                            case 57 /* AtToken */:
                                // Done
                                break;
                            case 5 /* WhitespaceTrivia */:
                                if (state === 2 /* SavingComments */) {
                                    pushComment(scanner.getTokenText());
                                }
                                else {
                                    var whitespace = scanner.getTokenText();
                                    // if the whitespace crosses the margin, take only the whitespace that passes the margin
                                    if (margin !== undefined && indent + whitespace.length > margin) {
                                        comments.push(whitespace.slice(margin - indent - 1));
                                    }
                                    indent += whitespace.length;
                                }
                                break;
                            case 39 /* AsteriskToken */:
                                if (state === 0 /* BeginningOfLine */) {
                                    // leading asterisks start recording on the *next* (non-whitespace) token
                                    state = 1 /* SawAsterisk */;
                                    indent += scanner.getTokenText().length;
                                    break;
                                }
                            // record the * as a comment
                            // falls through
                            default:
                                state = 2 /* SavingComments */; // leading identifiers start recording as well
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        if (token() === 57 /* AtToken */) {
                            // Done
                            break;
                        }
                        nextJSDocToken();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingNewlines(comments);
                    return comments;
                }
                function parseUnknownTag(atToken, tagName) {
                    var result = createNode(276 /* JSDocTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    return finishNode(result);
                }
                function addTag(tag, comments) {
                    tag.comment = comments.join("");
                    if (!tags) {
                        tags = [tag];
                        tagsPos = tag.pos;
                    }
                    else {
                        tags.push(tag);
                    }
                    tagsEnd = tag.end;
                }
                function tryParseTypeExpression() {
                    skipWhitespace();
                    return token() === 17 /* OpenBraceToken */ ? parseJSDocTypeExpression() : undefined;
                }
                function parseBracketNameInPropertyAndParamTag() {
                    // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar'
                    var isBracketed = parseOptional(21 /* OpenBracketToken */);
                    var name = parseJSDocEntityName();
                    if (isBracketed) {
                        skipWhitespace();
                        // May have an optional default, e.g. '[foo = 42]'
                        if (parseOptionalToken(58 /* EqualsToken */)) {
                            parseExpression();
                        }
                        parseExpected(22 /* CloseBracketToken */);
                    }
                    return { name: name, isBracketed: isBracketed };
                }
                function isObjectOrObjectArrayTypeReference(node) {
                    switch (node.kind) {
                        case 134 /* ObjectKeyword */:
                            return true;
                        case 164 /* ArrayType */:
                            return isObjectOrObjectArrayTypeReference(node.elementType);
                        default:
                            return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object";
                    }
                }
                function parseParameterOrPropertyTag(atToken, tagName, target) {
                    var typeExpression = tryParseTypeExpression();
                    var isNameFirst = !typeExpression;
                    skipWhitespace();
                    var _a = parseBracketNameInPropertyAndParamTag(), name = _a.name, isBracketed = _a.isBracketed;
                    skipWhitespace();
                    if (isNameFirst) {
                        typeExpression = tryParseTypeExpression();
                    }
                    var result = target === 1 /* Parameter */ ?
                        createNode(279 /* JSDocParameterTag */, atToken.pos) :
                        createNode(284 /* JSDocPropertyTag */, atToken.pos);
                    var nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name);
                    if (nestedTypeLiteral) {
                        typeExpression = nestedTypeLiteral;
                        isNameFirst = true;
                    }
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeExpression = typeExpression;
                    result.name = name;
                    result.isNameFirst = isNameFirst;
                    result.isBracketed = isBracketed;
                    return finishNode(result);
                }
                function parseNestedTypeLiteral(typeExpression, name) {
                    if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var typeLiteralExpression = createNode(267 /* JSDocTypeExpression */, scanner.getTokenPos());
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var start_2 = scanner.getStartPos();
                        var children = void 0;
                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(1 /* Parameter */, name); })) {
                            if (!children) {
                                children = [];
                            }
                            children.push(child);
                        }
                        if (children) {
                            jsdocTypeLiteral = createNode(285 /* JSDocTypeLiteral */, start_2);
                            jsdocTypeLiteral.jsDocPropertyTags = children;
                            if (typeExpression.type.kind === 164 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typeLiteralExpression.type = finishNode(jsdocTypeLiteral);
                            return finishNode(typeLiteralExpression);
                        }
                    }
                }
                function parseReturnTag(atToken, tagName) {
                    if (ts.forEach(tags, function (t) { return t.kind === 280 /* JSDocReturnTag */; })) {
                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(280 /* JSDocReturnTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeExpression = tryParseTypeExpression();
                    return finishNode(result);
                }
                function parseTypeTag(atToken, tagName) {
                    if (ts.forEach(tags, function (t) { return t.kind === 281 /* JSDocTypeTag */; })) {
                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(281 /* JSDocTypeTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeExpression = parseJSDocTypeExpression(/*requireBraces*/ true);
                    return finishNode(result);
                }
                function parseAugmentsTag(atToken, tagName) {
                    var result = createNode(277 /* JSDocAugmentsTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.class = parseExpressionWithTypeArgumentsForAugments();
                    return finishNode(result);
                }
                function parseExpressionWithTypeArgumentsForAugments() {
                    var usedBrace = parseOptional(17 /* OpenBraceToken */);
                    var node = createNode(201 /* ExpressionWithTypeArguments */);
                    node.expression = parsePropertyAccessEntityNameExpression();
                    node.typeArguments = tryParseTypeArguments();
                    var res = finishNode(node);
                    if (usedBrace) {
                        parseExpected(18 /* CloseBraceToken */);
                    }
                    return res;
                }
                function parsePropertyAccessEntityNameExpression() {
                    var node = parseJSDocIdentifierName(/*createIfMissing*/ true);
                    while (parseOptional(23 /* DotToken */)) {
                        var prop = createNode(179 /* PropertyAccessExpression */, node.pos);
                        prop.expression = node;
                        prop.name = parseJSDocIdentifierName();
                        node = finishNode(prop);
                    }
                    return node;
                }
                function parseClassTag(atToken, tagName) {
                    var tag = createNode(278 /* JSDocClassTag */, atToken.pos);
                    tag.atToken = atToken;
                    tag.tagName = tagName;
                    return finishNode(tag);
                }
                function parseTypedefTag(atToken, tagName) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespace();
                    var typedefTag = createNode(283 /* JSDocTypedefTag */, atToken.pos);
                    typedefTag.atToken = atToken;
                    typedefTag.tagName = tagName;
                    typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0);
                    if (typedefTag.fullName) {
                        var rightNode = typedefTag.fullName;
                        while (true) {
                            if (rightNode.kind === 71 /* Identifier */ || !rightNode.body) {
                                // if node is identifier - use it as name
                                // otherwise use name of the rightmost part that we were able to parse
                                typedefTag.name = rightNode.kind === 71 /* Identifier */ ? rightNode : rightNode.name;
                                break;
                            }
                            rightNode = rightNode.body;
                        }
                    }
                    skipWhitespace();
                    typedefTag.typeExpression = typeExpression;
                    if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var childTypeTag = void 0;
                        var start_3 = scanner.getStartPos();
                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0 /* Property */); })) {
                            if (!jsdocTypeLiteral) {
                                jsdocTypeLiteral = createNode(285 /* JSDocTypeLiteral */, start_3);
                            }
                            if (child.kind === 281 /* JSDocTypeTag */) {
                                if (childTypeTag) {
                                    break;
                                }
                                else {
                                    childTypeTag = child;
                                }
                            }
                            else {
                                if (!jsdocTypeLiteral.jsDocPropertyTags) {
                                    jsdocTypeLiteral.jsDocPropertyTags = [];
                                }
                                jsdocTypeLiteral.jsDocPropertyTags.push(child);
                            }
                        }
                        if (jsdocTypeLiteral) {
                            if (typeExpression && typeExpression.type.kind === 164 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
                                childTypeTag.typeExpression :
                                finishNode(jsdocTypeLiteral);
                        }
                    }
                    return finishNode(typedefTag);
                    function parseJSDocTypeNameWithNamespace(flags) {
                        var pos = scanner.getTokenPos();
                        var typeNameOrNamespaceName = parseJSDocIdentifierName();
                        if (typeNameOrNamespaceName && parseOptional(23 /* DotToken */)) {
                            var jsDocNamespaceNode = createNode(233 /* ModuleDeclaration */, pos);
                            jsDocNamespaceNode.flags |= flags;
                            jsDocNamespaceNode.name = typeNameOrNamespaceName;
                            jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(4 /* NestedNamespace */);
                            return finishNode(jsDocNamespaceNode);
                        }
                        if (typeNameOrNamespaceName && flags & 4 /* NestedNamespace */) {
                            typeNameOrNamespaceName.isInJSDocNamespace = true;
                        }
                        return typeNameOrNamespaceName;
                    }
                }
                function escapedTextsEqual(a, b) {
                    while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) {
                        if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) {
                            a = a.left;
                            b = b.left;
                        }
                        else {
                            return false;
                        }
                    }
                    return a.escapedText === b.escapedText;
                }
                function parseChildParameterOrPropertyTag(target, name) {
                    var canParseTag = true;
                    var seenAsterisk = false;
                    while (true) {
                        nextJSDocToken();
                        switch (token()) {
                            case 57 /* AtToken */:
                                if (canParseTag) {
                                    var child = tryParseChildTag(target);
                                    if (child && child.kind === 279 /* JSDocParameterTag */ &&
                                        (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
                                        return false;
                                    }
                                    return child;
                                }
                                seenAsterisk = false;
                                break;
                            case 4 /* NewLineTrivia */:
                                canParseTag = true;
                                seenAsterisk = false;
                                break;
                            case 39 /* AsteriskToken */:
                                if (seenAsterisk) {
                                    canParseTag = false;
                                }
                                seenAsterisk = true;
                                break;
                            case 71 /* Identifier */:
                                canParseTag = false;
                                break;
                            case 1 /* EndOfFileToken */:
                                return false;
                        }
                    }
                }
                function tryParseChildTag(target) {
                    ts.Debug.assert(token() === 57 /* AtToken */);
                    var atToken = createNode(57 /* AtToken */, scanner.getStartPos());
                    atToken.end = scanner.getTextPos();
                    nextJSDocToken();
                    var tagName = parseJSDocIdentifierName();
                    skipWhitespace();
                    if (!tagName) {
                        return false;
                    }
                    switch (tagName.escapedText) {
                        case "type":
                            return target === 0 /* Property */ && parseTypeTag(atToken, tagName);
                        case "prop":
                        case "property":
                            return target === 0 /* Property */ && parseParameterOrPropertyTag(atToken, tagName, target);
                        case "arg":
                        case "argument":
                        case "param":
                            return target === 1 /* Parameter */ && parseParameterOrPropertyTag(atToken, tagName, target);
                    }
                    return false;
                }
                function parseTemplateTag(atToken, tagName) {
                    if (ts.forEach(tags, function (t) { return t.kind === 282 /* JSDocTemplateTag */; })) {
                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    // Type parameter list looks like '@template T,U,V'
                    var typeParameters = [];
                    var typeParametersPos = getNodePos();
                    while (true) {
                        var name = parseJSDocIdentifierName();
                        skipWhitespace();
                        if (!name) {
                            parseErrorAtPosition(scanner.getStartPos(), 0, ts.Diagnostics.Identifier_expected);
                            return undefined;
                        }
                        var typeParameter = createNode(145 /* TypeParameter */, name.pos);
                        typeParameter.name = name;
                        finishNode(typeParameter);
                        typeParameters.push(typeParameter);
                        if (token() === 26 /* CommaToken */) {
                            nextJSDocToken();
                            skipWhitespace();
                        }
                        else {
                            break;
                        }
                    }
                    var result = createNode(282 /* JSDocTemplateTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
                    finishNode(result);
                    return result;
                }
                function nextJSDocToken() {
                    return currentToken = scanner.scanJSDocToken();
                }
                function parseJSDocEntityName() {
                    var entity = parseJSDocIdentifierName(/*createIfMissing*/ true);
                    if (parseOptional(21 /* OpenBracketToken */)) {
                        parseExpected(22 /* CloseBracketToken */);
                        // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking.
                        // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}>
                        // but it's not worth it to enforce that restriction.
                    }
                    while (parseOptional(23 /* DotToken */)) {
                        var name = parseJSDocIdentifierName(/*createIfMissing*/ true);
                        if (parseOptional(21 /* OpenBracketToken */)) {
                            parseExpected(22 /* CloseBracketToken */);
                        }
                        entity = createQualifiedName(entity, name);
                    }
                    return entity;
                }
                function parseJSDocIdentifierName(createIfMissing) {
                    if (createIfMissing === void 0) { createIfMissing = false; }
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        if (createIfMissing) {
                            return createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
                        }
                        else {
                            parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected);
                            return undefined;
                        }
                    }
                    var pos = scanner.getTokenPos();
                    var end = scanner.getTextPos();
                    var result = createNode(71 /* Identifier */, pos);
                    result.escapedText = ts.escapeLeadingUnderscores(content.substring(pos, end));
                    finishNode(result, end);
                    nextJSDocToken();
                    return result;
                }
            }
            JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
        })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
    })(Parser || (Parser = {}));
    var IncrementalParser;
    (function (IncrementalParser) {
        function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
            aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
            checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
            if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
                // if the text didn't change, then we can just return our current source file as-is.
                return sourceFile;
            }
            if (sourceFile.statements.length === 0) {
                // If we don't have any statements in the current source file, then there's no real
                // way to incrementally parse.  So just do a full parse instead.
                return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind);
            }
            // Make sure we're not trying to incrementally update a source file more than once.  Once
            // we do an update the original source file is considered unusable from that point onwards.
            //
            // This is because we do incremental parsing in-place.  i.e. we take nodes from the old
            // tree and give them new positions and parents.  From that point on, trusting the old
            // tree at all is not possible as far too much of it may violate invariants.
            var incrementalSourceFile = sourceFile;
            ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
            incrementalSourceFile.hasBeenIncrementallyParsed = true;
            var oldText = sourceFile.text;
            var syntaxCursor = createSyntaxCursor(sourceFile);
            // Make the actual change larger so that we know to reparse anything whose lookahead
            // might have intersected the change.
            var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
            checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
            // Ensure that extending the affected range only moved the start of the change range
            // earlier in the file.
            ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
            ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
            ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
            // The is the amount the nodes after the edit range need to be adjusted.  It can be
            // positive (if the edit added characters), negative (if the edit deleted characters)
            // or zero (if this was a pure overwrite with nothing added/removed).
            var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
            // If we added or removed characters during the edit, then we need to go and adjust all
            // the nodes after the edit.  Those nodes may move forward (if we inserted chars) or they
            // may move backward (if we deleted chars).
            //
            // Doing this helps us out in two ways.  First, it means that any nodes/tokens we want
            // to reuse are already at the appropriate position in the new text.  That way when we
            // reuse them, we don't have to figure out if they need to be adjusted.  Second, it makes
            // it very easy to determine if we can reuse a node.  If the node's position is at where
            // we are in the text, then we can reuse it.  Otherwise we can't.  If the node's position
            // is ahead of us, then we'll need to rescan tokens.  If the node's position is behind
            // us, then we'll need to skip it or crumble it as appropriate
            //
            // We will also adjust the positions of nodes that intersect the change range as well.
            // By doing this, we ensure that all the positions in the old tree are consistent, not
            // just the positions of nodes entirely before/after the change range.  By being
            // consistent, we can then easily map from positions to nodes in the old tree easily.
            //
            // Also, mark any syntax elements that intersect the changed span.  We know, up front,
            // that we cannot reuse these elements.
            updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
            // Now that we've set up our internal incremental state just proceed and parse the
            // source file in the normal fashion.  When possible the parser will retrieve and
            // reuse nodes from the old tree.
            //
            // Note: passing in 'true' for setNodeParents is very important.  When incrementally
            // parsing, we will be reusing nodes from the old tree, and placing it into new
            // parents.  If we don't set the parents now, we'll end up with an observably
            // inconsistent tree.  Setting the parents on the new tree should be very fast.  We
            // will immediately bail out of walking any subtrees when we can see that their parents
            // are already correct.
            var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind);
            return result;
        }
        IncrementalParser.updateSourceFile = updateSourceFile;
        function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
            if (isArray) {
                visitArray(element);
            }
            else {
                visitNode(element);
            }
            return;
            function visitNode(node) {
                var text = "";
                if (aggressiveChecks && shouldCheckNode(node)) {
                    text = oldText.substring(node.pos, node.end);
                }
                // Ditch any existing LS children we may have created.  This way we can avoid
                // moving them forward.
                if (node._children) {
                    node._children = undefined;
                }
                node.pos += delta;
                node.end += delta;
                if (aggressiveChecks && shouldCheckNode(node)) {
                    ts.Debug.assert(text === newText.substring(node.pos, node.end));
                }
                forEachChild(node, visitNode, visitArray);
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        forEachChild(jsDocComment, visitNode, visitArray);
                    }
                }
                checkNodePositions(node, aggressiveChecks);
            }
            function visitArray(array) {
                array._children = undefined;
                array.pos += delta;
                array.end += delta;
                for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
                    var node = array_8[_i];
                    visitNode(node);
                }
            }
        }
        function shouldCheckNode(node) {
            switch (node.kind) {
                case 9 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 71 /* Identifier */:
                    return true;
            }
            return false;
        }
        function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
            ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
            ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
            ts.Debug.assert(element.pos <= element.end);
            // We have an element that intersects the change range in some way.  It may have its
            // start, or its end (or both) in the changed range.  We want to adjust any part
            // that intersects such that the final tree is in a consistent state.  i.e. all
            // children have spans within the span of their parent, and all siblings are ordered
            // properly.
            // We may need to update both the 'pos' and the 'end' of the element.
            // If the 'pos' is before the start of the change, then we don't need to touch it.
            // If it isn't, then the 'pos' must be inside the change.  How we update it will
            // depend if delta is  positive or negative.  If delta is positive then we have
            // something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that started in the change range to still be
            // starting at the same position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that started in the 'X' range will keep its position.
            // However any element that started after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that started in the 'Y' range will
            // be adjusted to have their start at the end of the 'Z' range.
            //
            // The element will keep its position if possible.  Or Move backward to the new-end
            // if it's in the 'Y' range.
            element.pos = Math.min(element.pos, changeRangeNewEnd);
            // If the 'end' is after the change range, then we always adjust it by the delta
            // amount.  However, if the end is in the change range, then how we adjust it
            // will depend on if delta is  positive or negative.  If delta is positive then we
            // have something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that ended inside the change range to keep its
            // end position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that ended in the 'X' range will keep its position.
            // However any element that ended after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that ended in the 'Y' range will
            // be adjusted to have their end at the end of the 'Z' range.
            if (element.end >= changeRangeOldEnd) {
                // Element ends after the change range.  Always adjust the end pos.
                element.end += delta;
            }
            else {
                // Element ends in the change range.  The element will keep its position if
                // possible. Or Move backward to the new-end if it's in the 'Y' range.
                element.end = Math.min(element.end, changeRangeNewEnd);
            }
            ts.Debug.assert(element.pos <= element.end);
            if (element.parent) {
                ts.Debug.assert(element.pos >= element.parent.pos);
                ts.Debug.assert(element.end <= element.parent.end);
            }
        }
        function checkNodePositions(node, aggressiveChecks) {
            if (aggressiveChecks) {
                var pos_2 = node.pos;
                forEachChild(node, function (child) {
                    ts.Debug.assert(child.pos >= pos_2);
                    pos_2 = child.end;
                });
                ts.Debug.assert(pos_2 <= node.end);
            }
        }
        function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
            visitNode(sourceFile);
            return;
            function visitNode(child) {
                ts.Debug.assert(child.pos <= child.end);
                if (child.pos > changeRangeOldEnd) {
                    // Node is entirely past the change range.  We need to move both its pos and
                    // end, forward or backward appropriately.
                    moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = child.end;
                if (fullEnd >= changeStart) {
                    child.intersectsChange = true;
                    child._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting element accordingly.
                    adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    forEachChild(child, visitNode, visitArray);
                    checkNodePositions(child, aggressiveChecks);
                    return;
                }
                // Otherwise, the node is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
            function visitArray(array) {
                ts.Debug.assert(array.pos <= array.end);
                if (array.pos > changeRangeOldEnd) {
                    // Array is entirely after the change range.  We need to move it, and move any of
                    // its children.
                    moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = array.end;
                if (fullEnd >= changeStart) {
                    array.intersectsChange = true;
                    array._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting array accordingly.
                    adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    for (var _i = 0, array_9 = array; _i < array_9.length; _i++) {
                        var node = array_9[_i];
                        visitNode(node);
                    }
                    return;
                }
                // Otherwise, the array is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
        }
        function extendToAffectedRange(sourceFile, changeRange) {
            // Consider the following code:
            //      void foo() { /; }
            //
            // If the text changes with an insertion of / just before the semicolon then we end up with:
            //      void foo() { //; }
            //
            // If we were to just use the changeRange a is, then we would not rescan the { token
            // (as it does not intersect the actual original change range).  Because an edit may
            // change the token touching it, we actually need to look back *at least* one token so
            // that the prior token sees that change.
            var maxLookahead = 1;
            var start = changeRange.span.start;
            // the first iteration aligns us with the change start. subsequent iteration move us to
            // the left by maxLookahead tokens.  We only need to do this as long as we're not at the
            // start of the tree.
            for (var i = 0; start > 0 && i <= maxLookahead; i++) {
                var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
                ts.Debug.assert(nearestNode.pos <= start);
                var position = nearestNode.pos;
                start = Math.max(0, position - 1);
            }
            var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
            var finalLength = changeRange.newLength + (changeRange.span.start - start);
            return ts.createTextChangeRange(finalSpan, finalLength);
        }
        function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
            var bestResult = sourceFile;
            var lastNodeEntirelyBeforePosition;
            forEachChild(sourceFile, visit);
            if (lastNodeEntirelyBeforePosition) {
                var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
                if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
                    bestResult = lastChildOfLastEntireNodeBeforePosition;
                }
            }
            return bestResult;
            function getLastChild(node) {
                while (true) {
                    var lastChild = getLastChildWorker(node);
                    if (lastChild) {
                        node = lastChild;
                    }
                    else {
                        return node;
                    }
                }
            }
            function getLastChildWorker(node) {
                var last = undefined;
                forEachChild(node, function (child) {
                    if (ts.nodeIsPresent(child)) {
                        last = child;
                    }
                });
                return last;
            }
            function visit(child) {
                if (ts.nodeIsMissing(child)) {
                    // Missing nodes are effectively invisible to us.  We never even consider them
                    // When trying to find the nearest node before us.
                    return;
                }
                // If the child intersects this position, then this node is currently the nearest
                // node that starts before the position.
                if (child.pos <= position) {
                    if (child.pos >= bestResult.pos) {
                        // This node starts before the position, and is closer to the position than
                        // the previous best node we found.  It is now the new best node.
                        bestResult = child;
                    }
                    // Now, the node may overlap the position, or it may end entirely before the
                    // position.  If it overlaps with the position, then either it, or one of its
                    // children must be the nearest node before the position.  So we can just
                    // recurse into this child to see if we can find something better.
                    if (position < child.end) {
                        // The nearest node is either this child, or one of the children inside
                        // of it.  We've already marked this child as the best so far.  Recurse
                        // in case one of the children is better.
                        forEachChild(child, visit);
                        // Once we look at the children of this node, then there's no need to
                        // continue any further.
                        return true;
                    }
                    else {
                        ts.Debug.assert(child.end <= position);
                        // The child ends entirely before this position.  Say you have the following
                        // (where $ is the position)
                        //
                        //      <complex expr 1> ? <complex expr 2> $ : <...> <...>
                        //
                        // We would want to find the nearest preceding node in "complex expr 2".
                        // To support that, we keep track of this node, and once we're done searching
                        // for a best node, we recurse down this node to see if we can find a good
                        // result in it.
                        //
                        // This approach allows us to quickly skip over nodes that are entirely
                        // before the position, while still allowing us to find any nodes in the
                        // last one that might be what we want.
                        lastNodeEntirelyBeforePosition = child;
                    }
                }
                else {
                    ts.Debug.assert(child.pos > position);
                    // We're now at a node that is entirely past the position we're searching for.
                    // This node (and all following nodes) could never contribute to the result,
                    // so just skip them by returning 'true' here.
                    return true;
                }
            }
        }
        function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
            var oldText = sourceFile.text;
            if (textChangeRange) {
                ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
                if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
                    var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
                    var newTextPrefix = newText.substr(0, textChangeRange.span.start);
                    ts.Debug.assert(oldTextPrefix === newTextPrefix);
                    var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
                    var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
                    ts.Debug.assert(oldTextSuffix === newTextSuffix);
                }
            }
        }
        function createSyntaxCursor(sourceFile) {
            var currentArray = sourceFile.statements;
            var currentArrayIndex = 0;
            ts.Debug.assert(currentArrayIndex < currentArray.length);
            var current = currentArray[currentArrayIndex];
            var lastQueriedPosition = -1 /* Value */;
            return {
                currentNode: function (position) {
                    // Only compute the current node if the position is different than the last time
                    // we were asked.  The parser commonly asks for the node at the same position
                    // twice.  Once to know if can read an appropriate list element at a certain point,
                    // and then to actually read and consume the node.
                    if (position !== lastQueriedPosition) {
                        // Much of the time the parser will need the very next node in the array that
                        // we just returned a node from.So just simply check for that case and move
                        // forward in the array instead of searching for the node again.
                        if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
                            currentArrayIndex++;
                            current = currentArray[currentArrayIndex];
                        }
                        // If we don't have a node, or the node we have isn't in the right position,
                        // then try to find a viable node at the position requested.
                        if (!current || current.pos !== position) {
                            findHighestListElementThatStartsAtPosition(position);
                        }
                    }
                    // Cache this query so that we don't do any extra work if the parser calls back
                    // into us.  Note: this is very common as the parser will make pairs of calls like
                    // 'isListElement -> parseListElement'.  If we were unable to find a node when
                    // called with 'isListElement', we don't want to redo the work when parseListElement
                    // is called immediately after.
                    lastQueriedPosition = position;
                    // Either we don'd have a node, or we have a node at the position being asked for.
                    ts.Debug.assert(!current || current.pos === position);
                    return current;
                }
            };
            // Finds the highest element in the tree we can find that starts at the provided position.
            // The element must be a direct child of some node list in the tree.  This way after we
            // return it, we can easily return its next sibling in the list.
            function findHighestListElementThatStartsAtPosition(position) {
                // Clear out any cached state about the last node we found.
                currentArray = undefined;
                currentArrayIndex = -1 /* Value */;
                current = undefined;
                // Recurse into the source file to find the highest node at this position.
                forEachChild(sourceFile, visitNode, visitArray);
                return;
                function visitNode(node) {
                    if (position >= node.pos && position < node.end) {
                        // Position was within this node.  Keep searching deeper to find the node.
                        forEachChild(node, visitNode, visitArray);
                        // don't proceed any further in the search.
                        return true;
                    }
                    // position wasn't in this node, have to keep searching.
                    return false;
                }
                function visitArray(array) {
                    if (position >= array.pos && position < array.end) {
                        // position was in this array.  Search through this array to see if we find a
                        // viable element.
                        for (var i = 0; i < array.length; i++) {
                            var child = array[i];
                            if (child) {
                                if (child.pos === position) {
                                    // Found the right node.  We're done.
                                    currentArray = array;
                                    currentArrayIndex = i;
                                    current = child;
                                    return true;
                                }
                                else {
                                    if (child.pos < position && position < child.end) {
                                        // Position in somewhere within this child.  Search in it and
                                        // stop searching in this array.
                                        forEachChild(child, visitNode, visitArray);
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    // position wasn't in this array, have to keep searching.
                    return false;
                }
            }
        }
        var InvalidPosition;
        (function (InvalidPosition) {
            InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
        })(InvalidPosition || (InvalidPosition = {}));
    })(IncrementalParser || (IncrementalParser = {}));
})(ts || (ts = {}));
/// <reference path="utilities.ts"/>
/// <reference path="parser.ts"/>
/* @internal */
var ts;
(function (ts) {
    var ModuleInstanceState;
    (function (ModuleInstanceState) {
        ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
        ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
        ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
    })(ModuleInstanceState = ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
    function getModuleInstanceState(node) {
        // A module is uninstantiated if it contains only
        // 1. interface declarations, type alias declarations
        if (node.kind === 230 /* InterfaceDeclaration */ || node.kind === 231 /* TypeAliasDeclaration */) {
            return 0 /* NonInstantiated */;
        }
        else if (ts.isConstEnumDeclaration(node)) {
            return 2 /* ConstEnumOnly */;
        }
        else if ((node.kind === 238 /* ImportDeclaration */ || node.kind === 237 /* ImportEqualsDeclaration */) && !(ts.hasModifier(node, 1 /* Export */))) {
            return 0 /* NonInstantiated */;
        }
        else if (node.kind === 234 /* ModuleBlock */) {
            var state_1 = 0 /* NonInstantiated */;
            ts.forEachChild(node, function (n) {
                switch (getModuleInstanceState(n)) {
                    case 0 /* NonInstantiated */:
                        // child is non-instantiated - continue searching
                        return false;
                    case 2 /* ConstEnumOnly */:
                        // child is const enum only - record state and continue searching
                        state_1 = 2 /* ConstEnumOnly */;
                        return false;
                    case 1 /* Instantiated */:
                        // child is instantiated - record state and stop
                        state_1 = 1 /* Instantiated */;
                        return true;
                }
            });
            return state_1;
        }
        else if (node.kind === 233 /* ModuleDeclaration */) {
            var body = node.body;
            return body ? getModuleInstanceState(body) : 1 /* Instantiated */;
        }
        else if (node.kind === 71 /* Identifier */ && node.isInJSDocNamespace) {
            return 0 /* NonInstantiated */;
        }
        else {
            return 1 /* Instantiated */;
        }
    }
    ts.getModuleInstanceState = getModuleInstanceState;
    var ContainerFlags;
    (function (ContainerFlags) {
        // The current node is not a container, and no container manipulation should happen before
        // recursing into it.
        ContainerFlags[ContainerFlags["None"] = 0] = "None";
        // The current node is a container.  It should be set as the current container (and block-
        // container) before recursing into it.  The current node does not have locals.  Examples:
        //
        //      Classes, ObjectLiterals, TypeLiterals, Interfaces...
        ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
        // The current node is a block-scoped-container.  It should be set as the current block-
        // container before recursing into it.  Examples:
        //
        //      Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
        ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
        // The current node is the container of a control flow path. The current control flow should
        // be saved and restored, and a new control flow initialized within the container.
        ContainerFlags[ContainerFlags["IsControlFlowContainer"] = 4] = "IsControlFlowContainer";
        ContainerFlags[ContainerFlags["IsFunctionLike"] = 8] = "IsFunctionLike";
        ContainerFlags[ContainerFlags["IsFunctionExpression"] = 16] = "IsFunctionExpression";
        ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals";
        ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface";
        ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod";
    })(ContainerFlags || (ContainerFlags = {}));
    var binder = createBinder();
    function bindSourceFile(file, options) {
        ts.performance.mark("beforeBind");
        binder(file, options);
        ts.performance.mark("afterBind");
        ts.performance.measure("Bind", "beforeBind", "afterBind");
    }
    ts.bindSourceFile = bindSourceFile;
    function createBinder() {
        var file;
        var options;
        var languageVersion;
        var parent;
        var container;
        var blockScopeContainer;
        var lastContainer;
        var seenThisKeyword;
        // state used by control flow analysis
        var currentFlow;
        var currentBreakTarget;
        var currentContinueTarget;
        var currentReturnTarget;
        var currentTrueTarget;
        var currentFalseTarget;
        var preSwitchCaseFlow;
        var activeLabels;
        var hasExplicitReturn;
        // state used for emit helpers
        var emitFlags;
        // If this file is an external module, then it is automatically in strict-mode according to
        // ES6.  If it is not an external module, then we'll determine if it is in strict mode or
        // not depending on if we see "use strict" in certain places or if we hit a class/namespace
        // or if compiler options contain alwaysStrict.
        var inStrictMode;
        var symbolCount = 0;
        var Symbol;
        var classifiableNames;
        var unreachableFlow = { flags: 1 /* Unreachable */ };
        var reportedUnreachableFlow = { flags: 1 /* Unreachable */ };
        // state used to aggregate transform flags during bind.
        var subtreeTransformFlags = 0 /* None */;
        var skipTransformFlagAggregation;
        /**
         * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file)
         * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node)
         * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations.
         */
        function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
            return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2);
        }
        function bindSourceFile(f, opts) {
            file = f;
            options = opts;
            languageVersion = ts.getEmitScriptTarget(options);
            inStrictMode = bindInStrictMode(file, opts);
            classifiableNames = ts.createUnderscoreEscapedMap();
            symbolCount = 0;
            skipTransformFlagAggregation = file.isDeclarationFile;
            Symbol = ts.objectAllocator.getSymbolConstructor();
            if (!file.locals) {
                bind(file);
                file.symbolCount = symbolCount;
                file.classifiableNames = classifiableNames;
            }
            file = undefined;
            options = undefined;
            languageVersion = undefined;
            parent = undefined;
            container = undefined;
            blockScopeContainer = undefined;
            lastContainer = undefined;
            seenThisKeyword = false;
            currentFlow = undefined;
            currentBreakTarget = undefined;
            currentContinueTarget = undefined;
            currentReturnTarget = undefined;
            currentTrueTarget = undefined;
            currentFalseTarget = undefined;
            activeLabels = undefined;
            hasExplicitReturn = false;
            emitFlags = 0 /* None */;
            subtreeTransformFlags = 0 /* None */;
        }
        return bindSourceFile;
        function bindInStrictMode(file, opts) {
            if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !file.isDeclarationFile) {
                // bind in strict mode source files with alwaysStrict option
                return true;
            }
            else {
                return !!file.externalModuleIndicator;
            }
        }
        function createSymbol(flags, name) {
            symbolCount++;
            return new Symbol(flags, name);
        }
        function addDeclarationToSymbol(symbol, node, symbolFlags) {
            symbol.flags |= symbolFlags;
            node.symbol = symbol;
            if (!symbol.declarations) {
                symbol.declarations = [node];
            }
            else {
                symbol.declarations.push(node);
            }
            if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
                symbol.exports = ts.createSymbolTable();
            }
            if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
                symbol.members = ts.createSymbolTable();
            }
            if (symbolFlags & 107455 /* Value */) {
                var valueDeclaration = symbol.valueDeclaration;
                if (!valueDeclaration ||
                    (valueDeclaration.kind !== node.kind && valueDeclaration.kind === 233 /* ModuleDeclaration */)) {
                    // other kinds of value declarations take precedence over modules
                    symbol.valueDeclaration = node;
                }
            }
        }
        // Should not be called on a declaration with a computed property name,
        // unless it is a well known Symbol.
        function getDeclarationName(node) {
            if (node.kind === 243 /* ExportAssignment */) {
                return node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */;
            }
            var name = ts.getNameOfDeclaration(node);
            if (name) {
                if (ts.isAmbientModule(node)) {
                    var moduleName = ts.getTextOfIdentifierOrLiteral(name);
                    return (ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + moduleName + "\"");
                }
                if (name.kind === 144 /* ComputedPropertyName */) {
                    var nameExpression = name.expression;
                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
                    if (ts.isStringOrNumericLiteral(nameExpression)) {
                        return ts.escapeLeadingUnderscores(nameExpression.text);
                    }
                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
                    return ts.getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                return ts.getEscapedTextOfIdentifierOrLiteral(name);
            }
            switch (node.kind) {
                case 152 /* Constructor */:
                    return "__constructor" /* Constructor */;
                case 160 /* FunctionType */:
                case 155 /* CallSignature */:
                    return "__call" /* Call */;
                case 161 /* ConstructorType */:
                case 156 /* ConstructSignature */:
                    return "__new" /* New */;
                case 157 /* IndexSignature */:
                    return "__index" /* Index */;
                case 244 /* ExportDeclaration */:
                    return "__export" /* ExportStar */;
                case 194 /* BinaryExpression */:
                    if (ts.getSpecialPropertyAssignmentKind(node) === 2 /* ModuleExports */) {
                        // module.exports = ...
                        return "export=" /* ExportEquals */;
                    }
                    ts.Debug.fail("Unknown binary declaration kind");
                    break;
                case 228 /* FunctionDeclaration */:
                case 229 /* ClassDeclaration */:
                    return (ts.hasModifier(node, 512 /* Default */) ? "default" /* Default */ : undefined);
                case 273 /* JSDocFunctionType */:
                    return (ts.isJSDocConstructSignature(node) ? "__new" /* New */ : "__call" /* Call */);
                case 146 /* Parameter */:
                    // Parameters with names are handled at the top of this function.  Parameters
                    // without names can only come from JSDocFunctionTypes.
                    ts.Debug.assert(node.parent.kind === 273 /* JSDocFunctionType */);
                    var functionType = node.parent;
                    var index = ts.indexOf(functionType.parameters, node);
                    return "arg" + index;
                case 283 /* JSDocTypedefTag */:
                    var name_2 = ts.getNameOfJSDocTypedef(node);
                    return typeof name_2 !== "undefined" ? name_2.escapedText : undefined;
            }
        }
        function getDisplayName(node) {
            return node.name ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(getDeclarationName(node));
        }
        /**
         * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
         * @param symbolTable - The symbol table which node will be added to.
         * @param parent - node's parent declaration.
         * @param node - The declaration to be added to the symbol table
         * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
         * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
         */
        function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod) {
            ts.Debug.assert(!ts.hasDynamicName(node));
            var isDefaultExport = ts.hasModifier(node, 512 /* Default */);
            // The exported symbol for an export default function/class node is always named "default"
            var name = isDefaultExport && parent ? "default" /* Default */ : getDeclarationName(node);
            var symbol;
            if (name === undefined) {
                symbol = createSymbol(0 /* None */, "__missing" /* Missing */);
            }
            else {
                // Check and see if the symbol table already has a symbol with this name.  If not,
                // create a new symbol with this name and add it to the table.  Note that we don't
                // give the new symbol any flags *yet*.  This ensures that it will not conflict
                // with the 'excludes' flags we pass in.
                //
                // If we do get an existing symbol, see if it conflicts with the new symbol we're
                // creating.  For example, a 'var' symbol and a 'class' symbol will conflict within
                // the same symbol table.  If we have a conflict, report the issue on each
                // declaration we have for this symbol, and then create a new symbol for this
                // declaration.
                //
                // Note that when properties declared in Javascript constructors
                // (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
                // Always. This allows the common Javascript pattern of overwriting a prototype method
                // with an bound instance method of the same type: `this.method = this.method.bind(this)`
                //
                // If we created a new symbol, either because we didn't have a symbol with this name
                // in the symbol table, or we conflicted with an existing symbol, then just add this
                // node as the sole declaration of the new symbol.
                //
                // Otherwise, we'll be merging into a compatible existing symbol (for example when
                // you have multiple 'vars' with the same name in the same container).  In this case
                // just add this node into the declarations list of the symbol.
                symbol = symbolTable.get(name);
                if (includes & 788448 /* Classifiable */) {
                    classifiableNames.set(name, true);
                }
                if (!symbol) {
                    symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    if (isReplaceableByMethod)
                        symbol.isReplaceableByMethod = true;
                }
                else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
                    // A symbol already exists, so don't add this as a declaration.
                    return symbol;
                }
                else if (symbol.flags & excludes) {
                    if (symbol.isReplaceableByMethod) {
                        // Javascript constructor-declared symbols can be discarded in favor of
                        // prototype symbols like methods.
                        symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    }
                    else {
                        if (node.name) {
                            node.name.parent = node;
                        }
                        // Report errors every position with duplicate declaration
                        // Report errors on previous encountered declarations
                        var message_1 = symbol.flags & 2 /* BlockScopedVariable */
                            ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                            : ts.Diagnostics.Duplicate_identifier_0;
                        if (symbol.declarations && symbol.declarations.length) {
                            // If the current node is a default export of some sort, then check if
                            // there are any other default exports that we need to error on.
                            // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
                            if (isDefaultExport) {
                                message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                            }
                            else {
                                // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
                                // Error on multiple export default in the following case:
                                // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
                                // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
                                if (symbol.declarations && symbol.declarations.length &&
                                    (isDefaultExport || (node.kind === 243 /* ExportAssignment */ && !node.isExportEquals))) {
                                    message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                }
                            }
                        }
                        ts.forEach(symbol.declarations, function (declaration) {
                            file.bindDiagnostics.push(createDiagnosticForNode(ts.getNameOfDeclaration(declaration) || declaration, message_1, getDisplayName(declaration)));
                        });
                        file.bindDiagnostics.push(createDiagnosticForNode(ts.getNameOfDeclaration(node) || node, message_1, getDisplayName(node)));
                        symbol = createSymbol(0 /* None */, name);
                    }
                }
            }
            addDeclarationToSymbol(symbol, node, includes);
            symbol.parent = parent;
            return symbol;
        }
        function declareModuleMember(node, symbolFlags, symbolExcludes) {
            var hasExportModifier = ts.getCombinedModifierFlags(node) & 1 /* Export */;
            if (symbolFlags & 2097152 /* Alias */) {
                if (node.kind === 246 /* ExportSpecifier */ || (node.kind === 237 /* ImportEqualsDeclaration */ && hasExportModifier)) {
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
            else {
                // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag,
                // and an associated export symbol with all the correct flags set on it. There are 2 main reasons:
                //
                //   1. We treat locals and exports of the same name as mutually exclusive within a container.
                //      That means the binder will issue a Duplicate Identifier error if you mix locals and exports
                //      with the same name in the same container.
                //      TODO: Make this a more specific error and decouple it from the exclusion logic.
                //   2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
                //      but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
                //      when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
                // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
                //       during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
                //       and this case is specially handled. Module augmentations should only be merged with original module definition
                //       and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
                if (node.kind === 283 /* JSDocTypedefTag */)
                    ts.Debug.assert(ts.isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
                var isJSDocTypedefInJSDocNamespace = node.kind === 283 /* JSDocTypedefTag */ &&
                    node.name &&
                    node.name.kind === 71 /* Identifier */ &&
                    node.name.isInJSDocNamespace;
                if ((!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 32 /* ExportContext */)) || isJSDocTypedefInJSDocNamespace) {
                    var exportKind = symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0;
                    var local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
                    local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                    node.localSymbol = local;
                    return local;
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
        }
        // All container nodes are kept on a linked list in declaration order. This list is used by
        // the getLocalNameOfContainer function in the type checker to validate that the local name
        // used for a container is unique.
        function bindContainer(node, containerFlags) {
            // Before we recurse into a node's children, we first save the existing parent, container
            // and block-container.  Then after we pop out of processing the children, we restore
            // these saved values.
            var saveContainer = container;
            var savedBlockScopeContainer = blockScopeContainer;
            // Depending on what kind of node this is, we may have to adjust the current container
            // and block-container.   If the current node is a container, then it is automatically
            // considered the current block-container as well.  Also, for containers that we know
            // may contain locals, we proactively initialize the .locals field. We do this because
            // it's highly likely that the .locals will be needed to place some child in (for example,
            // a parameter, or variable declaration).
            //
            // However, we do not proactively create the .locals for block-containers because it's
            // totally normal and common for block-containers to never actually have a block-scoped
            // variable in them.  We don't want to end up allocating an object for every 'block' we
            // run into when most of them won't be necessary.
            //
            // Finally, if this is a block-container, then we clear out any existing .locals object
            // it may contain within it.  This happens in incremental scenarios.  Because we can be
            // reusing a node from a previous compilation, that node may have had 'locals' created
            // for it.  We must clear this so we don't accidentally move any stale data forward from
            // a previous compilation.
            if (containerFlags & 1 /* IsContainer */) {
                container = blockScopeContainer = node;
                if (containerFlags & 32 /* HasLocals */) {
                    container.locals = ts.createSymbolTable();
                }
                addToContainerChain(container);
            }
            else if (containerFlags & 2 /* IsBlockScopedContainer */) {
                blockScopeContainer = node;
                blockScopeContainer.locals = undefined;
            }
            if (containerFlags & 4 /* IsControlFlowContainer */) {
                var saveCurrentFlow = currentFlow;
                var saveBreakTarget = currentBreakTarget;
                var saveContinueTarget = currentContinueTarget;
                var saveReturnTarget = currentReturnTarget;
                var saveActiveLabels = activeLabels;
                var saveHasExplicitReturn = hasExplicitReturn;
                var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !ts.hasModifier(node, 256 /* Async */) && !!ts.getImmediatelyInvokedFunctionExpression(node);
                // A non-async IIFE is considered part of the containing control flow. Return statements behave
                // similarly to break statements that exit to a label just past the statement body.
                if (isIIFE) {
                    currentReturnTarget = createBranchLabel();
                }
                else {
                    currentFlow = { flags: 2 /* Start */ };
                    if (containerFlags & (16 /* IsFunctionExpression */ | 128 /* IsObjectLiteralOrClassExpressionMethod */)) {
                        currentFlow.container = node;
                    }
                    currentReturnTarget = undefined;
                }
                currentBreakTarget = undefined;
                currentContinueTarget = undefined;
                activeLabels = undefined;
                hasExplicitReturn = false;
                bindChildren(node);
                // Reset all reachability check related flags on node (for incremental scenarios)
                node.flags &= ~1408 /* ReachabilityAndEmitFlags */;
                if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
                    node.flags |= 128 /* HasImplicitReturn */;
                    if (hasExplicitReturn)
                        node.flags |= 256 /* HasExplicitReturn */;
                }
                if (node.kind === 265 /* SourceFile */) {
                    node.flags |= emitFlags;
                }
                if (isIIFE) {
                    addAntecedent(currentReturnTarget, currentFlow);
                    currentFlow = finishFlowLabel(currentReturnTarget);
                }
                else {
                    currentFlow = saveCurrentFlow;
                }
                currentBreakTarget = saveBreakTarget;
                currentContinueTarget = saveContinueTarget;
                currentReturnTarget = saveReturnTarget;
                activeLabels = saveActiveLabels;
                hasExplicitReturn = saveHasExplicitReturn;
            }
            else if (containerFlags & 64 /* IsInterface */) {
                seenThisKeyword = false;
                bindChildren(node);
                node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */;
            }
            else {
                bindChildren(node);
            }
            container = saveContainer;
            blockScopeContainer = savedBlockScopeContainer;
        }
        function bindChildren(node) {
            if (skipTransformFlagAggregation) {
                bindChildrenWorker(node);
            }
            else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
                skipTransformFlagAggregation = true;
                bindChildrenWorker(node);
                skipTransformFlagAggregation = false;
                subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0;
                bindChildrenWorker(node);
                subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
            }
        }
        function bindEach(nodes) {
            if (nodes === undefined) {
                return;
            }
            if (skipTransformFlagAggregation) {
                ts.forEach(nodes, bind);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0 /* None */;
                var nodeArrayFlags = 0 /* None */;
                for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                    var node = nodes_2[_i];
                    bind(node);
                    nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
                }
                nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
                subtreeTransformFlags |= savedSubtreeTransformFlags;
            }
        }
        function bindEachChild(node) {
            ts.forEachChild(node, bind, bindEach);
        }
        function bindChildrenWorker(node) {
            // Binding of JsDocComment should be done before the current block scope container changes.
            // because the scope of JsDocComment should not be affected by whether the current node is a
            // container or not.
            if (ts.hasJSDocNodes(node)) {
                if (ts.isInJavaScriptFile(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var j = _a[_i];
                        bind(j);
                    }
                }
                else {
                    for (var _b = 0, _c = node.jsDoc; _b < _c.length; _b++) {
                        var j = _c[_b];
                        setParentPointers(node, j);
                    }
                }
            }
            if (checkUnreachable(node)) {
                bindEachChild(node);
                return;
            }
            switch (node.kind) {
                case 213 /* WhileStatement */:
                    bindWhileStatement(node);
                    break;
                case 212 /* DoStatement */:
                    bindDoStatement(node);
                    break;
                case 214 /* ForStatement */:
                    bindForStatement(node);
                    break;
                case 215 /* ForInStatement */:
                case 216 /* ForOfStatement */:
                    bindForInOrForOfStatement(node);
                    break;
                case 211 /* IfStatement */:
                    bindIfStatement(node);
                    break;
                case 219 /* ReturnStatement */:
                case 223 /* ThrowStatement */:
                    bindReturnOrThrow(node);
                    break;
                case 218 /* BreakStatement */:
                case 217 /* ContinueStatement */:
                    bindBreakOrContinueStatement(node);
                    break;
                case 224 /* TryStatement */:
                    bindTryStatement(node);
                    break;
                case 221 /* SwitchStatement */:
                    bindSwitchStatement(node);
                    break;
                case 235 /* CaseBlock */:
                    bindCaseBlock(node);
                    break;
                case 257 /* CaseClause */:
                    bindCaseClause(node);
                    break;
                case 222 /* LabeledStatement */:
                    bindLabeledStatement(node);
                    break;
                case 192 /* PrefixUnaryExpression */:
                    bindPrefixUnaryExpressionFlow(node);
                    break;
                case 193 /* PostfixUnaryExpression */:
                    bindPostfixUnaryExpressionFlow(node);
                    break;
                case 194 /* BinaryExpression */:
                    bindBinaryExpressionFlow(node);
                    break;
                case 188 /* DeleteExpression */:
                    bindDeleteExpressionFlow(node);
                    break;
                case 195 /* ConditionalExpression */:
                    bindConditionalExpressionFlow(node);
                    break;
                case 226 /* VariableDeclaration */:
                    bindVariableDeclarationFlow(node);
                    break;
                case 181 /* CallExpression */:
                    bindCallExpressionFlow(node);
                    break;
                case 275 /* JSDocComment */:
                    bindJSDocComment(node);
                    break;
                case 283 /* JSDocTypedefTag */:
                    bindJSDocTypedefTag(node);
                    break;
                default:
                    bindEachChild(node);
                    break;
            }
        }
        function isNarrowingExpression(expr) {
            switch (expr.kind) {
                case 71 /* Identifier */:
                case 99 /* ThisKeyword */:
                case 179 /* PropertyAccessExpression */:
                    return isNarrowableReference(expr);
                case 181 /* CallExpression */:
                    return hasNarrowableArgument(expr);
                case 185 /* ParenthesizedExpression */:
                    return isNarrowingExpression(expr.expression);
                case 194 /* BinaryExpression */:
                    return isNarrowingBinaryExpression(expr);
                case 192 /* PrefixUnaryExpression */:
                    return expr.operator === 51 /* ExclamationToken */ && isNarrowingExpression(expr.operand);
            }
            return false;
        }
        function isNarrowableReference(expr) {
            return expr.kind === 71 /* Identifier */ ||
                expr.kind === 99 /* ThisKeyword */ ||
                expr.kind === 97 /* SuperKeyword */ ||
                expr.kind === 179 /* PropertyAccessExpression */ && isNarrowableReference(expr.expression);
        }
        function hasNarrowableArgument(expr) {
            if (expr.arguments) {
                for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (isNarrowableReference(argument)) {
                        return true;
                    }
                }
            }
            if (expr.expression.kind === 179 /* PropertyAccessExpression */ &&
                isNarrowableReference(expr.expression.expression)) {
                return true;
            }
            return false;
        }
        function isNarrowingTypeofOperands(expr1, expr2) {
            return expr1.kind === 189 /* TypeOfExpression */ && isNarrowableOperand(expr1.expression) && expr2.kind === 9 /* StringLiteral */;
        }
        function isNarrowingBinaryExpression(expr) {
            switch (expr.operatorToken.kind) {
                case 58 /* EqualsToken */:
                    return isNarrowableReference(expr.left);
                case 32 /* EqualsEqualsToken */:
                case 33 /* ExclamationEqualsToken */:
                case 34 /* EqualsEqualsEqualsToken */:
                case 35 /* ExclamationEqualsEqualsToken */:
                    return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
                        isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
                case 93 /* InstanceOfKeyword */:
                    return isNarrowableOperand(expr.left);
                case 26 /* CommaToken */:
                    return isNarrowingExpression(expr.right);
            }
            return false;
        }
        function isNarrowableOperand(expr) {
            switch (expr.kind) {
                case 185 /* ParenthesizedExpression */:
                    return isNarrowableOperand(expr.expression);
                case 194 /* BinaryExpression */:
                    switch (expr.operatorToken.kind) {
                        case 58 /* EqualsToken */:
                            return isNarrowableOperand(expr.left);
                        case 26 /* CommaToken */:
                            return isNarrowableOperand(expr.right);
                    }
            }
            return isNarrowableReference(expr);
        }
        function createBranchLabel() {
            return {
                flags: 4 /* BranchLabel */,
                antecedents: undefined
            };
        }
        function createLoopLabel() {
            return {
                flags: 8 /* LoopLabel */,
                antecedents: undefined
            };
        }
        function setFlowNodeReferenced(flow) {
            // On first reference we set the Referenced flag, thereafter we set the Shared flag
            flow.flags |= flow.flags & 512 /* Referenced */ ? 1024 /* Shared */ : 512 /* Referenced */;
        }
        function addAntecedent(label, antecedent) {
            if (!(antecedent.flags & 1 /* Unreachable */) && !ts.contains(label.antecedents, antecedent)) {
                (label.antecedents || (label.antecedents = [])).push(antecedent);
                setFlowNodeReferenced(antecedent);
            }
        }
        function createFlowCondition(flags, antecedent, expression) {
            if (antecedent.flags & 1 /* Unreachable */) {
                return antecedent;
            }
            if (!expression) {
                return flags & 32 /* TrueCondition */ ? antecedent : unreachableFlow;
            }
            if (expression.kind === 101 /* TrueKeyword */ && flags & 64 /* FalseCondition */ ||
                expression.kind === 86 /* FalseKeyword */ && flags & 32 /* TrueCondition */) {
                return unreachableFlow;
            }
            if (!isNarrowingExpression(expression)) {
                return antecedent;
            }
            setFlowNodeReferenced(antecedent);
            return { flags: flags, expression: expression, antecedent: antecedent };
        }
        function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) {
            if (!isNarrowingExpression(switchStatement.expression)) {
                return antecedent;
            }
            setFlowNodeReferenced(antecedent);
            return { flags: 128 /* SwitchClause */, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent };
        }
        function createFlowAssignment(antecedent, node) {
            setFlowNodeReferenced(antecedent);
            return { flags: 16 /* Assignment */, antecedent: antecedent, node: node };
        }
        function createFlowArrayMutation(antecedent, node) {
            setFlowNodeReferenced(antecedent);
            var res = { flags: 256 /* ArrayMutation */, antecedent: antecedent, node: node };
            return res;
        }
        function finishFlowLabel(flow) {
            var antecedents = flow.antecedents;
            if (!antecedents) {
                return unreachableFlow;
            }
            if (antecedents.length === 1) {
                return antecedents[0];
            }
            return flow;
        }
        function isStatementCondition(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 211 /* IfStatement */:
                case 213 /* WhileStatement */:
                case 212 /* DoStatement */:
                    return parent.expression === node;
                case 214 /* ForStatement */:
                case 195 /* ConditionalExpression */:
                    return parent.condition === node;
            }
            return false;
        }
        function isLogicalExpression(node) {
            while (true) {
                if (node.kind === 185 /* ParenthesizedExpression */) {
                    node = node.expression;
                }
                else if (node.kind === 192 /* PrefixUnaryExpression */ && node.operator === 51 /* ExclamationToken */) {
                    node = node.operand;
                }
                else {
                    return node.kind === 194 /* BinaryExpression */ && (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */ ||
                        node.operatorToken.kind === 54 /* BarBarToken */);
                }
            }
        }
        function isTopLevelLogicalExpression(node) {
            while (node.parent.kind === 185 /* ParenthesizedExpression */ ||
                node.parent.kind === 192 /* PrefixUnaryExpression */ &&
                    node.parent.operator === 51 /* ExclamationToken */) {
                node = node.parent;
            }
            return !isStatementCondition(node) && !isLogicalExpression(node.parent);
        }
        function bindCondition(node, trueTarget, falseTarget) {
            var saveTrueTarget = currentTrueTarget;
            var saveFalseTarget = currentFalseTarget;
            currentTrueTarget = trueTarget;
            currentFalseTarget = falseTarget;
            bind(node);
            currentTrueTarget = saveTrueTarget;
            currentFalseTarget = saveFalseTarget;
            if (!node || !isLogicalExpression(node)) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindIterativeStatement(node, breakTarget, continueTarget) {
            var saveBreakTarget = currentBreakTarget;
            var saveContinueTarget = currentContinueTarget;
            currentBreakTarget = breakTarget;
            currentContinueTarget = continueTarget;
            bind(node);
            currentBreakTarget = saveBreakTarget;
            currentContinueTarget = saveContinueTarget;
        }
        function bindWhileStatement(node) {
            var preWhileLabel = createLoopLabel();
            var preBodyLabel = createBranchLabel();
            var postWhileLabel = createBranchLabel();
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = preWhileLabel;
            bindCondition(node.expression, preBodyLabel, postWhileLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel);
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = finishFlowLabel(postWhileLabel);
        }
        function bindDoStatement(node) {
            var preDoLabel = createLoopLabel();
            var enclosingLabeledStatement = node.parent.kind === 222 /* LabeledStatement */
                ? ts.lastOrUndefined(activeLabels)
                : undefined;
            // if do statement is wrapped in labeled statement then target labels for break/continue with or without
            // label should be the same
            var preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel();
            var postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel();
            addAntecedent(preDoLabel, currentFlow);
            currentFlow = preDoLabel;
            bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
            addAntecedent(preConditionLabel, currentFlow);
            currentFlow = finishFlowLabel(preConditionLabel);
            bindCondition(node.expression, preDoLabel, postDoLabel);
            currentFlow = finishFlowLabel(postDoLabel);
        }
        function bindForStatement(node) {
            var preLoopLabel = createLoopLabel();
            var preBodyLabel = createBranchLabel();
            var postLoopLabel = createBranchLabel();
            bind(node.initializer);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            bindCondition(node.condition, preBodyLabel, postLoopLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            bind(node.incrementor);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindForInOrForOfStatement(node) {
            var preLoopLabel = createLoopLabel();
            var postLoopLabel = createBranchLabel();
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            if (node.kind === 216 /* ForOfStatement */) {
                bind(node.awaitModifier);
            }
            bind(node.expression);
            addAntecedent(postLoopLabel, currentFlow);
            bind(node.initializer);
            if (node.initializer.kind !== 227 /* VariableDeclarationList */) {
                bindAssignmentTargetFlow(node.initializer);
            }
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindIfStatement(node) {
            var thenLabel = createBranchLabel();
            var elseLabel = createBranchLabel();
            var postIfLabel = createBranchLabel();
            bindCondition(node.expression, thenLabel, elseLabel);
            currentFlow = finishFlowLabel(thenLabel);
            bind(node.thenStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(elseLabel);
            bind(node.elseStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(postIfLabel);
        }
        function bindReturnOrThrow(node) {
            bind(node.expression);
            if (node.kind === 219 /* ReturnStatement */) {
                hasExplicitReturn = true;
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                }
            }
            currentFlow = unreachableFlow;
        }
        function findActiveLabel(name) {
            if (activeLabels) {
                for (var _i = 0, activeLabels_1 = activeLabels; _i < activeLabels_1.length; _i++) {
                    var label = activeLabels_1[_i];
                    if (label.name === name) {
                        return label;
                    }
                }
            }
            return undefined;
        }
        function bindBreakOrContinueFlow(node, breakTarget, continueTarget) {
            var flowLabel = node.kind === 218 /* BreakStatement */ ? breakTarget : continueTarget;
            if (flowLabel) {
                addAntecedent(flowLabel, currentFlow);
                currentFlow = unreachableFlow;
            }
        }
        function bindBreakOrContinueStatement(node) {
            bind(node.label);
            if (node.label) {
                var activeLabel = findActiveLabel(node.label.escapedText);
                if (activeLabel) {
                    activeLabel.referenced = true;
                    bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
                }
            }
            else {
                bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
            }
        }
        function bindTryStatement(node) {
            var preFinallyLabel = createBranchLabel();
            var preTryFlow = currentFlow;
            // TODO: Every statement in try block is potentially an exit point!
            bind(node.tryBlock);
            addAntecedent(preFinallyLabel, currentFlow);
            var flowAfterTry = currentFlow;
            var flowAfterCatch = unreachableFlow;
            if (node.catchClause) {
                currentFlow = preTryFlow;
                bind(node.catchClause);
                addAntecedent(preFinallyLabel, currentFlow);
                flowAfterCatch = currentFlow;
            }
            if (node.finallyBlock) {
                // in finally flow is combined from pre-try/flow from try/flow from catch
                // pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
                // also for finally blocks we inject two extra edges into the flow graph.
                // first -> edge that connects pre-try flow with the label at the beginning of the finally block, it has lock associated with it
                // second -> edge that represents post-finally flow.
                // these edges are used in following scenario:
                // let a; (1)
                // try { a = someOperation(); (2)}
                // finally { (3) console.log(a) } (4)
                // (5) a
                // flow graph for this case looks roughly like this (arrows show ):
                // (1-pre-try-flow) <--.. <-- (2-post-try-flow)
                //  ^                                ^
                //  |*****(3-pre-finally-label) -----|
                //                ^
                //                |-- ... <-- (4-post-finally-label) <--- (5)
                // In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account
                // since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5)
                // then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable
                // Simply speaking code inside finally block is treated as reachable as pre-try-flow
                // since we conservatively assume that any line in try block can throw or return in which case we'll enter finally.
                // However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from
                // final flows of these blocks without taking pre-try flow into account.
                //
                // extra edges that we inject allows to control this behavior
                // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped.
                var preFinallyFlow = { flags: 2048 /* PreFinally */, antecedent: preTryFlow, lock: {} };
                addAntecedent(preFinallyLabel, preFinallyFlow);
                currentFlow = finishFlowLabel(preFinallyLabel);
                bind(node.finallyBlock);
                // if flow after finally is unreachable - keep it
                // otherwise check if flows after try and after catch are unreachable
                // if yes - convert current flow to unreachable
                // i.e.
                // try { return "1" } finally { console.log(1); }
                // console.log(2); // this line should be unreachable even if flow falls out of finally block
                if (!(currentFlow.flags & 1 /* Unreachable */)) {
                    if ((flowAfterTry.flags & 1 /* Unreachable */) && (flowAfterCatch.flags & 1 /* Unreachable */)) {
                        currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow
                            ? reportedUnreachableFlow
                            : unreachableFlow;
                    }
                }
                if (!(currentFlow.flags & 1 /* Unreachable */)) {
                    var afterFinallyFlow = { flags: 4096 /* AfterFinally */, antecedent: currentFlow };
                    preFinallyFlow.lock = afterFinallyFlow;
                    currentFlow = afterFinallyFlow;
                }
            }
            else {
                currentFlow = finishFlowLabel(preFinallyLabel);
            }
        }
        function bindSwitchStatement(node) {
            var postSwitchLabel = createBranchLabel();
            bind(node.expression);
            var saveBreakTarget = currentBreakTarget;
            var savePreSwitchCaseFlow = preSwitchCaseFlow;
            currentBreakTarget = postSwitchLabel;
            preSwitchCaseFlow = currentFlow;
            bind(node.caseBlock);
            addAntecedent(postSwitchLabel, currentFlow);
            var hasDefault = ts.forEach(node.caseBlock.clauses, function (c) { return c.kind === 258 /* DefaultClause */; });
            // We mark a switch statement as possibly exhaustive if it has no default clause and if all
            // case clauses have unreachable end points (e.g. they all return).
            node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
            if (!hasDefault) {
                addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
            }
            currentBreakTarget = saveBreakTarget;
            preSwitchCaseFlow = savePreSwitchCaseFlow;
            currentFlow = finishFlowLabel(postSwitchLabel);
        }
        function bindCaseBlock(node) {
            var savedSubtreeTransformFlags = subtreeTransformFlags;
            subtreeTransformFlags = 0;
            var clauses = node.clauses;
            var fallthroughFlow = unreachableFlow;
            for (var i = 0; i < clauses.length; i++) {
                var clauseStart = i;
                while (!clauses[i].statements.length && i + 1 < clauses.length) {
                    bind(clauses[i]);
                    i++;
                }
                var preCaseLabel = createBranchLabel();
                addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1));
                addAntecedent(preCaseLabel, fallthroughFlow);
                currentFlow = finishFlowLabel(preCaseLabel);
                var clause = clauses[i];
                bind(clause);
                fallthroughFlow = currentFlow;
                if (!(currentFlow.flags & 1 /* Unreachable */) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) {
                    errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
                }
            }
            clauses.transformFlags = subtreeTransformFlags | 536870912 /* HasComputedFlags */;
            subtreeTransformFlags |= savedSubtreeTransformFlags;
        }
        function bindCaseClause(node) {
            var saveCurrentFlow = currentFlow;
            currentFlow = preSwitchCaseFlow;
            bind(node.expression);
            currentFlow = saveCurrentFlow;
            bindEach(node.statements);
        }
        function pushActiveLabel(name, breakTarget, continueTarget) {
            var activeLabel = {
                name: name,
                breakTarget: breakTarget,
                continueTarget: continueTarget,
                referenced: false
            };
            (activeLabels || (activeLabels = [])).push(activeLabel);
            return activeLabel;
        }
        function popActiveLabel() {
            activeLabels.pop();
        }
        function bindLabeledStatement(node) {
            var preStatementLabel = createLoopLabel();
            var postStatementLabel = createBranchLabel();
            bind(node.label);
            addAntecedent(preStatementLabel, currentFlow);
            var activeLabel = pushActiveLabel(node.label.escapedText, postStatementLabel, preStatementLabel);
            bind(node.statement);
            popActiveLabel();
            if (!activeLabel.referenced && !options.allowUnusedLabels) {
                file.bindDiagnostics.push(createDiagnosticForNode(node.label, ts.Diagnostics.Unused_label));
            }
            if (!node.statement || node.statement.kind !== 212 /* DoStatement */) {
                // do statement sets current flow inside bindDoStatement
                addAntecedent(postStatementLabel, currentFlow);
                currentFlow = finishFlowLabel(postStatementLabel);
            }
        }
        function bindDestructuringTargetFlow(node) {
            if (node.kind === 194 /* BinaryExpression */ && node.operatorToken.kind === 58 /* EqualsToken */) {
                bindAssignmentTargetFlow(node.left);
            }
            else {
                bindAssignmentTargetFlow(node);
            }
        }
        function bindAssignmentTargetFlow(node) {
            if (isNarrowableReference(node)) {
                currentFlow = createFlowAssignment(currentFlow, node);
            }
            else if (node.kind === 177 /* ArrayLiteralExpression */) {
                for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                    var e = _a[_i];
                    if (e.kind === 198 /* SpreadElement */) {
                        bindAssignmentTargetFlow(e.expression);
                    }
                    else {
                        bindDestructuringTargetFlow(e);
                    }
                }
            }
            else if (node.kind === 178 /* ObjectLiteralExpression */) {
                for (var _b = 0, _c = node.properties; _b < _c.length; _b++) {
                    var p = _c[_b];
                    if (p.kind === 261 /* PropertyAssignment */) {
                        bindDestructuringTargetFlow(p.initializer);
                    }
                    else if (p.kind === 262 /* ShorthandPropertyAssignment */) {
                        bindAssignmentTargetFlow(p.name);
                    }
                    else if (p.kind === 263 /* SpreadAssignment */) {
                        bindAssignmentTargetFlow(p.expression);
                    }
                }
            }
        }
        function bindLogicalExpression(node, trueTarget, falseTarget) {
            var preRightLabel = createBranchLabel();
            if (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */) {
                bindCondition(node.left, preRightLabel, falseTarget);
            }
            else {
                bindCondition(node.left, trueTarget, preRightLabel);
            }
            currentFlow = finishFlowLabel(preRightLabel);
            bind(node.operatorToken);
            bindCondition(node.right, trueTarget, falseTarget);
        }
        function bindPrefixUnaryExpressionFlow(node) {
            if (node.operator === 51 /* ExclamationToken */) {
                var saveTrueTarget = currentTrueTarget;
                currentTrueTarget = currentFalseTarget;
                currentFalseTarget = saveTrueTarget;
                bindEachChild(node);
                currentFalseTarget = currentTrueTarget;
                currentTrueTarget = saveTrueTarget;
            }
            else {
                bindEachChild(node);
                if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) {
                    bindAssignmentTargetFlow(node.operand);
                }
            }
        }
        function bindPostfixUnaryExpressionFlow(node) {
            bindEachChild(node);
            if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) {
                bindAssignmentTargetFlow(node.operand);
            }
        }
        function bindBinaryExpressionFlow(node) {
            var operator = node.operatorToken.kind;
            if (operator === 53 /* AmpersandAmpersandToken */ || operator === 54 /* BarBarToken */) {
                if (isTopLevelLogicalExpression(node)) {
                    var postExpressionLabel = createBranchLabel();
                    bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
                    currentFlow = finishFlowLabel(postExpressionLabel);
                }
                else {
                    bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
                }
            }
            else {
                bindEachChild(node);
                if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) {
                    bindAssignmentTargetFlow(node.left);
                    if (operator === 58 /* EqualsToken */ && node.left.kind === 180 /* ElementAccessExpression */) {
                        var elementAccess = node.left;
                        if (isNarrowableOperand(elementAccess.expression)) {
                            currentFlow = createFlowArrayMutation(currentFlow, node);
                        }
                    }
                }
            }
        }
        function bindDeleteExpressionFlow(node) {
            bindEachChild(node);
            if (node.expression.kind === 179 /* PropertyAccessExpression */) {
                bindAssignmentTargetFlow(node.expression);
            }
        }
        function bindConditionalExpressionFlow(node) {
            var trueLabel = createBranchLabel();
            var falseLabel = createBranchLabel();
            var postExpressionLabel = createBranchLabel();
            bindCondition(node.condition, trueLabel, falseLabel);
            currentFlow = finishFlowLabel(trueLabel);
            bind(node.questionToken);
            bind(node.whenTrue);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(falseLabel);
            bind(node.colonToken);
            bind(node.whenFalse);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(postExpressionLabel);
        }
        function bindInitializedVariableFlow(node) {
            var name = !ts.isOmittedExpression(node) ? node.name : undefined;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var child = _a[_i];
                    bindInitializedVariableFlow(child);
                }
            }
            else {
                currentFlow = createFlowAssignment(currentFlow, node);
            }
        }
        function bindVariableDeclarationFlow(node) {
            bindEachChild(node);
            if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) {
                bindInitializedVariableFlow(node);
            }
        }
        function bindJSDocComment(node) {
            ts.forEachChild(node, function (n) {
                if (n.kind !== 283 /* JSDocTypedefTag */) {
                    bind(n);
                }
            });
        }
        function bindJSDocTypedefTag(node) {
            ts.forEachChild(node, function (n) {
                // if the node has a fullName "A.B.C", that means symbol "C" was already bound
                // when we visit "fullName"; so when we visit the name "C" as the next child of
                // the jsDocTypedefTag, we should skip binding it.
                if (node.fullName && n === node.name && node.fullName.kind !== 71 /* Identifier */) {
                    return;
                }
                bind(n);
            });
        }
        function bindCallExpressionFlow(node) {
            // If the target of the call expression is a function expression or arrow function we have
            // an immediately invoked function expression (IIFE). Initialize the flowNode property to
            // the current control flow (which includes evaluation of the IIFE arguments).
            var expr = node.expression;
            while (expr.kind === 185 /* ParenthesizedExpression */) {
                expr = expr.expression;
            }
            if (expr.kind === 186 /* FunctionExpression */ || expr.kind === 187 /* ArrowFunction */) {
                bindEach(node.typeArguments);
                bindEach(node.arguments);
                bind(node.expression);
            }
            else {
                bindEachChild(node);
            }
            if (node.expression.kind === 179 /* PropertyAccessExpression */) {
                var propertyAccess = node.expression;
                if (isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) {
                    currentFlow = createFlowArrayMutation(currentFlow, node);
                }
            }
        }
        function getContainerFlags(node) {
            switch (node.kind) {
                case 199 /* ClassExpression */:
                case 229 /* ClassDeclaration */:
                case 232 /* EnumDeclaration */:
                case 178 /* ObjectLiteralExpression */:
                case 163 /* TypeLiteral */:
                case 285 /* JSDocTypeLiteral */:
                case 254 /* JsxAttributes */:
                    return 1 /* IsContainer */;
                case 230 /* InterfaceDeclaration */:
                    return 1 /* IsContainer */ | 64 /* IsInterface */;
                case 233 /* ModuleDeclaration */:
                case 231 /* TypeAliasDeclaration */:
                case 172 /* MappedType */:
                    return 1 /* IsContainer */ | 32 /* HasLocals */;
                case 265 /* SourceFile */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */;
                case 151 /* MethodDeclaration */:
                    if (ts.isObjectLiteralOrClassExpressionMethod(node)) {
                        return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 128 /* IsObjectLiteralOrClassExpressionMethod */;
                    }
                // falls through
                case 152 /* Constructor */:
                case 228 /* FunctionDeclaration */:
                case 150 /* MethodSignature */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 155 /* CallSignature */:
                case 273 /* JSDocFunctionType */:
                case 160 /* FunctionType */:
                case 156 /* ConstructSignature */:
                case 157 /* IndexSignature */:
                case 161 /* ConstructorType */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */;
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */;
                case 234 /* ModuleBlock */:
                    return 4 /* IsControlFlowContainer */;
                case 149 /* PropertyDeclaration */:
                    return node.initializer ? 4 /* IsControlFlowContainer */ : 0;
                case 260 /* CatchClause */:
                case 214 /* ForStatement */:
                case 215 /* ForInStatement */:
                case 216 /* ForOfStatement */:
                case 235 /* CaseBlock */:
                    return 2 /* IsBlockScopedContainer */;
                case 207 /* Block */:
                    // do not treat blocks directly inside a function as a block-scoped-container.
                    // Locals that reside in this block should go to the function locals. Otherwise 'x'
                    // would not appear to be a redeclaration of a block scoped local in the following
                    // example:
                    //
                    //      function foo() {
                    //          var x;
                    //          let x;
                    //      }
                    //
                    // If we placed 'var x' into the function locals and 'let x' into the locals of
                    // the block, then there would be no collision.
                    //
                    // By not creating a new block-scoped-container here, we ensure that both 'var x'
                    // and 'let x' go into the Function-container's locals, and we do get a collision
                    // conflict.
                    return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
            }
            return 0 /* None */;
        }
        function addToContainerChain(next) {
            if (lastContainer) {
                lastContainer.nextContainer = next;
            }
            lastContainer = next;
        }
        function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
            switch (container.kind) {
                // Modules, source files, and classes need specialized handling for how their
                // members are declared (for example, a member of a class will go into a specific
                // symbol table depending on if it is static or not). We defer to specialized
                // handlers to take care of declaring these child members.
                case 233 /* ModuleDeclaration */:
                    return declareModuleMember(node, symbolFlags, symbolExcludes);
                case 265 /* SourceFile */:
                    return declareSourceFileMember(node, symbolFlags, symbolExcludes);
                case 199 /* ClassExpression */:
                case 229 /* ClassDeclaration */:
                    return declareClassMember(node, symbolFlags, symbolExcludes);
                case 232 /* EnumDeclaration */:
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                case 163 /* TypeLiteral */:
                case 285 /* JSDocTypeLiteral */:
                case 178 /* ObjectLiteralExpression */:
                case 230 /* InterfaceDeclaration */:
                case 254 /* JsxAttributes */:
                    // Interface/Object-types always have their children added to the 'members' of
                    // their container. They are only accessible through an instance of their
                    // container, and are never in scope otherwise (even inside the body of the
                    // object / type / interface declaring them). An exception is type parameters,
                    // which are in scope without qualification (similar to 'locals').
                    return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
                case 160 /* FunctionType */:
                case 161 /* ConstructorType */:
                case 155 /* CallSignature */:
                case 156 /* ConstructSignature */:
                case 157 /* IndexSignature */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 152 /* Constructor */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                case 273 /* JSDocFunctionType */:
                case 231 /* TypeAliasDeclaration */:
                case 172 /* MappedType */:
                    // All the children of these container types are never visible through another
                    // symbol (i.e. through another symbol's 'exports' or 'members').  Instead,
                    // they're only accessed 'lexically' (i.e. from code that exists underneath
                    // their container in the tree). To accomplish this, we simply add their declared
                    // symbol to the 'locals' of the container.  These symbols can then be found as
                    // the type checker walks up the containers, checking them for matching names.
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function declareClassMember(node, symbolFlags, symbolExcludes) {
            return ts.hasModifier(node, 32 /* Static */)
                ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
                : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
        }
        function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
            return ts.isExternalModule(file)
                ? declareModuleMember(node, symbolFlags, symbolExcludes)
                : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
        }
        function hasExportDeclarations(node) {
            var body = node.kind === 265 /* SourceFile */ ? node : node.body;
            if (body && (body.kind === 265 /* SourceFile */ || body.kind === 234 /* ModuleBlock */)) {
                for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
                    var stat = _a[_i];
                    if (stat.kind === 244 /* ExportDeclaration */ || stat.kind === 243 /* ExportAssignment */) {
                        return true;
                    }
                }
            }
            return false;
        }
        function setExportContextFlag(node) {
            // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
            // declarations with export modifiers) is an export context in which declarations are implicitly exported.
            if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
                node.flags |= 32 /* ExportContext */;
            }
            else {
                node.flags &= ~32 /* ExportContext */;
            }
        }
        function bindModuleDeclaration(node) {
            setExportContextFlag(node);
            if (ts.isAmbientModule(node)) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
                }
                if (ts.isExternalModuleAugmentation(node)) {
                    declareModuleSymbol(node);
                }
                else {
                    var pattern = void 0;
                    if (node.name.kind === 9 /* StringLiteral */) {
                        var text = node.name.text;
                        if (ts.hasZeroOrOneAsteriskCharacter(text)) {
                            pattern = ts.tryParsePattern(text);
                        }
                        else {
                            errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text);
                        }
                    }
                    var symbol = declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
                    if (pattern) {
                        (file.patternAmbientModules || (file.patternAmbientModules = [])).push({ pattern: pattern, symbol: symbol });
                    }
                }
            }
            else {
                var state = declareModuleSymbol(node);
                if (state !== 0 /* NonInstantiated */) {
                    if (node.symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)) {
                        // if module was already merged with some function, class or non-const enum
                        // treat is a non-const-enum-only
                        node.symbol.constEnumOnlyModule = false;
                    }
                    else {
                        var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */;
                        if (node.symbol.constEnumOnlyModule === undefined) {
                            // non-merged case - use the current state
                            node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
                        }
                        else {
                            // merged case: module is const enum only if all its pieces are non-instantiated or const enum
                            node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
                        }
                    }
                }
            }
        }
        function declareModuleSymbol(node) {
            var state = getModuleInstanceState(node);
            var instantiated = state !== 0 /* NonInstantiated */;
            declareSymbolAndAddToSymbolTable(node, instantiated ? 512 /* ValueModule */ : 1024 /* NamespaceModule */, instantiated ? 106639 /* ValueModuleExcludes */ : 0 /* NamespaceModuleExcludes */);
            return state;
        }
        function bindFunctionOrConstructorType(node) {
            // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
            // to the one we would get for: { <...>(...): T }
            //
            // We do that by making an anonymous type literal symbol, and then setting the function
            // symbol as its sole member. To the rest of the system, this symbol will be  indistinguishable
            // from an actual type literal symbol you would have gotten had you used the long form.
            var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node));
            addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
            var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
            addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
            typeLiteralSymbol.members = ts.createSymbolTable();
            typeLiteralSymbol.members.set(symbol.escapedName, symbol);
        }
        function bindObjectLiteralExpression(node) {
            var ElementKind;
            (function (ElementKind) {
                ElementKind[ElementKind["Property"] = 1] = "Property";
                ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
            })(ElementKind || (ElementKind = {}));
            if (inStrictMode) {
                var seen = ts.createUnderscoreEscapedMap();
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (prop.kind === 263 /* SpreadAssignment */ || prop.name.kind !== 71 /* Identifier */) {
                        continue;
                    }
                    var identifier = prop.name;
                    // ECMA-262 11.1.5 Object Initializer
                    // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                    // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                    // IsDataDescriptor(propId.descriptor) is true.
                    //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                    //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                    //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                    // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                    var currentKind = prop.kind === 261 /* PropertyAssignment */ || prop.kind === 262 /* ShorthandPropertyAssignment */ || prop.kind === 151 /* MethodDeclaration */
                        ? 1 /* Property */
                        : 2 /* Accessor */;
                    var existingKind = seen.get(identifier.escapedText);
                    if (!existingKind) {
                        seen.set(identifier.escapedText, currentKind);
                        continue;
                    }
                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
                        var span_1 = ts.getErrorSpanForNode(file, identifier);
                        file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_1.start, span_1.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
                    }
                }
            }
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object" /* Object */);
        }
        function bindJsxAttributes(node) {
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__jsxAttributes" /* JSXAttributes */);
        }
        function bindJsxAttribute(node, symbolFlags, symbolExcludes) {
            return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function bindAnonymousDeclaration(node, symbolFlags, name) {
            var symbol = createSymbol(symbolFlags, name);
            if (symbolFlags & 8 /* EnumMember */) {
                symbol.parent = container.symbol;
            }
            addDeclarationToSymbol(symbol, node, symbolFlags);
        }
        function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
            switch (blockScopeContainer.kind) {
                case 233 /* ModuleDeclaration */:
                    declareModuleMember(node, symbolFlags, symbolExcludes);
                    break;
                case 265 /* SourceFile */:
                    if (ts.isExternalModule(container)) {
                        declareModuleMember(node, symbolFlags, symbolExcludes);
                        break;
                    }
                // falls through
                default:
                    if (!blockScopeContainer.locals) {
                        blockScopeContainer.locals = ts.createSymbolTable();
                        addToContainerChain(blockScopeContainer);
                    }
                    declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function bindBlockScopedVariableDeclaration(node) {
            bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
        }
        // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
        // check for reserved words used as identifiers in strict mode code.
        function checkStrictModeIdentifier(node) {
            if (inStrictMode &&
                node.originalKeywordKind >= 108 /* FirstFutureReservedWord */ &&
                node.originalKeywordKind <= 116 /* LastFutureReservedWord */ &&
                !ts.isIdentifierName(node) &&
                !ts.isInAmbientContext(node)) {
                // Report error only if there are no parse errors in file
                if (!file.parseDiagnostics.length) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
                }
            }
        }
        function getStrictModeIdentifierMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
        }
        function checkStrictModeBinaryExpression(node) {
            if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
                // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
                // Assignment operator(11.13) or of a PostfixExpression(11.3)
                checkStrictModeEvalOrArguments(node, node.left);
            }
        }
        function checkStrictModeCatchClause(node) {
            // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
            // Catch production is eval or arguments
            if (inStrictMode && node.variableDeclaration) {
                checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
            }
        }
        function checkStrictModeDeleteExpression(node) {
            // Grammar checking
            if (inStrictMode && node.expression.kind === 71 /* Identifier */) {
                // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
                // UnaryExpression is a direct reference to a variable, function argument, or function name
                var span_2 = ts.getErrorSpanForNode(file, node.expression);
                file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_2.start, span_2.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
            }
        }
        function isEvalOrArgumentsIdentifier(node) {
            return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
        }
        function checkStrictModeEvalOrArguments(contextNode, name) {
            if (name && name.kind === 71 /* Identifier */) {
                var identifier = name;
                if (isEvalOrArgumentsIdentifier(identifier)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var span_3 = ts.getErrorSpanForNode(file, name);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_3.start, span_3.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier)));
                }
            }
        }
        function getStrictModeEvalOrArgumentsMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
        }
        function checkStrictModeFunctionName(node) {
            if (inStrictMode) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
                checkStrictModeEvalOrArguments(node, node.name);
            }
        }
        function getStrictModeBlockScopeFunctionDeclarationMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5;
        }
        function checkStrictModeFunctionDeclaration(node) {
            if (languageVersion < 2 /* ES2015 */) {
                // Report error if function is not top level function declaration
                if (blockScopeContainer.kind !== 265 /* SourceFile */ &&
                    blockScopeContainer.kind !== 233 /* ModuleDeclaration */ &&
                    !ts.isFunctionLike(blockScopeContainer)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var errorSpan = ts.getErrorSpanForNode(file, node);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node)));
                }
            }
        }
        function checkStrictModeNumericLiteral(node) {
            if (inStrictMode && node.numericLiteralFlags & 4 /* Octal */) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
            }
        }
        function checkStrictModePostfixUnaryExpression(node) {
            // Grammar checking
            // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
            // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
            // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.operand);
            }
        }
        function checkStrictModePrefixUnaryExpression(node) {
            // Grammar checking
            if (inStrictMode) {
                if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) {
                    checkStrictModeEvalOrArguments(node, node.operand);
                }
            }
        }
        function checkStrictModeWithStatement(node) {
            // Grammar checking for withStatement
            if (inStrictMode) {
                errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
            }
        }
        function errorOnFirstToken(node, message, arg0, arg1, arg2) {
            var span = ts.getSpanOfTokenAtPosition(file, node.pos);
            file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
        }
        function bind(node) {
            if (!node) {
                return;
            }
            node.parent = parent;
            var saveInStrictMode = inStrictMode;
            // Even though in the AST the jsdoc @typedef node belongs to the current node,
            // its symbol might be in the same scope with the current node's symbol. Consider:
            //
            //     /** @typedef {string | number} MyType */
            //     function foo();
            //
            // Here the current node is "foo", which is a container, but the scope of "MyType" should
            // not be inside "foo". Therefore we always bind @typedef before bind the parent node,
            // and skip binding this tag later when binding all the other jsdoc tags.
            if (ts.isInJavaScriptFile(node))
                bindJSDocTypedefTagIfAny(node);
            // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
            // and then potentially add the symbol to an appropriate symbol table. Possible
            // destination symbol tables are:
            //
            //  1) The 'exports' table of the current container's symbol.
            //  2) The 'members' table of the current container's symbol.
            //  3) The 'locals' table of the current container.
            //
            // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
            // (like TypeLiterals for example) will not be put in any table.
            bindWorker(node);
            // Then we recurse into the children of the node to bind them as well. For certain
            // symbols we do specialized work when we recurse. For example, we'll keep track of
            // the current 'container' node when it changes. This helps us know which symbol table
            // a local should go into for example. Since terminal nodes are known not to have
            // children, as an optimization we don't process those.
            if (node.kind > 142 /* LastToken */) {
                var saveParent = parent;
                parent = node;
                var containerFlags = getContainerFlags(node);
                if (containerFlags === 0 /* None */) {
                    bindChildren(node);
                }
                else {
                    bindContainer(node, containerFlags);
                }
                parent = saveParent;
            }
            else if (!skipTransformFlagAggregation && (node.transformFlags & 536870912 /* HasComputedFlags */) === 0) {
                subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
            }
            inStrictMode = saveInStrictMode;
        }
        function bindJSDocTypedefTagIfAny(node) {
            if (!ts.hasJSDocNodes(node)) {
                return;
            }
            for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                var jsDoc = _a[_i];
                if (!jsDoc.tags) {
                    continue;
                }
                for (var _b = 0, _c = jsDoc.tags; _b < _c.length; _b++) {
                    var tag = _c[_b];
                    if (tag.kind === 283 /* JSDocTypedefTag */) {
                        var savedParent = parent;
                        parent = jsDoc;
                        bind(tag);
                        parent = savedParent;
                    }
                }
            }
        }
        function updateStrictModeStatementList(statements) {
            if (!inStrictMode) {
                for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
                    var statement = statements_1[_i];
                    if (!ts.isPrologueDirective(statement)) {
                        return;
                    }
                    if (isUseStrictPrologueDirective(statement)) {
                        inStrictMode = true;
                        return;
                    }
                }
            }
        }
        /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
        function isUseStrictPrologueDirective(node) {
            var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
            // Note: the node text must be exactly "use strict" or 'use strict'.  It is not ok for the
            // string to contain unicode escapes (as per ES5).
            return nodeText === '"use strict"' || nodeText === "'use strict'";
        }
        function bindWorker(node) {
            switch (node.kind) {
                /* Strict mode checks */
                case 71 /* Identifier */:
                    // for typedef type names with namespaces, bind the new jsdoc type symbol here
                    // because it requires all containing namespaces to be in effect, namely the
                    // current "blockScopeContainer" needs to be set to its immediate namespace parent.
                    if (node.isInJSDocNamespace) {
                        var parentNode = node.parent;
                        while (parentNode && parentNode.kind !== 283 /* JSDocTypedefTag */) {
                            parentNode = parentNode.parent;
                        }
                        bindBlockScopedDeclaration(parentNode, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */);
                        break;
                    }
                // falls through
                case 99 /* ThisKeyword */:
                    if (currentFlow && (ts.isExpression(node) || parent.kind === 262 /* ShorthandPropertyAssignment */)) {
                        node.flowNode = currentFlow;
                    }
                    return checkStrictModeIdentifier(node);
                case 179 /* PropertyAccessExpression */:
                    if (currentFlow && isNarrowableReference(node)) {
                        node.flowNode = currentFlow;
                    }
                    break;
                case 194 /* BinaryExpression */:
                    var specialKind = ts.getSpecialPropertyAssignmentKind(node);
                    switch (specialKind) {
                        case 1 /* ExportsProperty */:
                            bindExportsPropertyAssignment(node);
                            break;
                        case 2 /* ModuleExports */:
                            bindModuleExportsAssignment(node);
                            break;
                        case 3 /* PrototypeProperty */:
                            bindPrototypePropertyAssignment(node);
                            break;
                        case 4 /* ThisProperty */:
                            bindThisPropertyAssignment(node);
                            break;
                        case 5 /* Property */:
                            bindStaticPropertyAssignment(node);
                            break;
                        case 0 /* None */:
                            // Nothing to do
                            break;
                        default:
                            ts.Debug.fail("Unknown special property assignment kind");
                    }
                    return checkStrictModeBinaryExpression(node);
                case 260 /* CatchClause */:
                    return checkStrictModeCatchClause(node);
                case 188 /* DeleteExpression */:
                    return checkStrictModeDeleteExpression(node);
                case 8 /* NumericLiteral */:
                    return checkStrictModeNumericLiteral(node);
                case 193 /* PostfixUnaryExpression */:
                    return checkStrictModePostfixUnaryExpression(node);
                case 192 /* PrefixUnaryExpression */:
                    return checkStrictModePrefixUnaryExpression(node);
                case 220 /* WithStatement */:
                    return checkStrictModeWithStatement(node);
                case 169 /* ThisType */:
                    seenThisKeyword = true;
                    return;
                case 158 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 145 /* TypeParameter */:
                    return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530920 /* TypeParameterExcludes */);
                case 146 /* Parameter */:
                    return bindParameter(node);
                case 226 /* VariableDeclaration */:
                    return bindVariableDeclarationOrBindingElement(node);
                case 176 /* BindingElement */:
                    node.flowNode = currentFlow;
                    return bindVariableDeclarationOrBindingElement(node);
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    return bindPropertyWorker(node);
                case 261 /* PropertyAssignment */:
                case 262 /* ShorthandPropertyAssignment */:
                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */);
                case 264 /* EnumMember */:
                    return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 900095 /* EnumMemberExcludes */);
                case 155 /* CallSignature */:
                case 156 /* ConstructSignature */:
                case 157 /* IndexSignature */:
                    return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                    // If this is an ObjectLiteralExpression method, then it sits in the same space
                    // as other properties in the object literal.  So we use SymbolFlags.PropertyExcludes
                    // so that it will conflict with any other object literal members with the same
                    // name.
                    return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
                case 228 /* FunctionDeclaration */:
                    return bindFunctionDeclaration(node);
                case 152 /* Constructor */:
                    return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
                case 153 /* GetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
                case 154 /* SetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
                case 160 /* FunctionType */:
                case 273 /* JSDocFunctionType */:
                case 161 /* ConstructorType */:
                    return bindFunctionOrConstructorType(node);
                case 163 /* TypeLiteral */:
                case 285 /* JSDocTypeLiteral */:
                case 172 /* MappedType */:
                    return bindAnonymousTypeWorker(node);
                case 178 /* ObjectLiteralExpression */:
                    return bindObjectLiteralExpression(node);
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    return bindFunctionExpression(node);
                case 181 /* CallExpression */:
                    if (ts.isInJavaScriptFile(node)) {
                        bindCallExpression(node);
                    }
                    break;
                // Members of classes, interfaces, and modules
                case 199 /* ClassExpression */:
                case 229 /* ClassDeclaration */:
                    // All classes are automatically in strict mode in ES6.
                    inStrictMode = true;
                    return bindClassLikeDeclaration(node);
                case 230 /* InterfaceDeclaration */:
                    return bindBlockScopedDeclaration(node, 64 /* Interface */, 792968 /* InterfaceExcludes */);
                case 231 /* TypeAliasDeclaration */:
                    return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */);
                case 232 /* EnumDeclaration */:
                    return bindEnumDeclaration(node);
                case 233 /* ModuleDeclaration */:
                    return bindModuleDeclaration(node);
                // Jsx-attributes
                case 254 /* JsxAttributes */:
                    return bindJsxAttributes(node);
                case 253 /* JsxAttribute */:
                    return bindJsxAttribute(node, 4 /* Property */, 0 /* PropertyExcludes */);
                // Imports and exports
                case 237 /* ImportEqualsDeclaration */:
                case 240 /* NamespaceImport */:
                case 242 /* ImportSpecifier */:
                case 246 /* ExportSpecifier */:
                    return declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
                case 236 /* NamespaceExportDeclaration */:
                    return bindNamespaceExportDeclaration(node);
                case 239 /* ImportClause */:
                    return bindImportClause(node);
                case 244 /* ExportDeclaration */:
                    return bindExportDeclaration(node);
                case 243 /* ExportAssignment */:
                    return bindExportAssignment(node);
                case 265 /* SourceFile */:
                    updateStrictModeStatementList(node.statements);
                    return bindSourceFileIfExternalModule();
                case 207 /* Block */:
                    if (!ts.isFunctionLike(node.parent)) {
                        return;
                    }
                // falls through
                case 234 /* ModuleBlock */:
                    return updateStrictModeStatementList(node.statements);
                case 279 /* JSDocParameterTag */:
                    if (node.parent.kind !== 285 /* JSDocTypeLiteral */) {
                        break;
                    }
                // falls through
                case 284 /* JSDocPropertyTag */:
                    var propTag = node;
                    var flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === 272 /* JSDocOptionalType */ ?
                        4 /* Property */ | 16777216 /* Optional */ :
                        4 /* Property */;
                    return declareSymbolAndAddToSymbolTable(propTag, flags, 0 /* PropertyExcludes */);
                case 283 /* JSDocTypedefTag */: {
                    var fullName = node.fullName;
                    if (!fullName || fullName.kind === 71 /* Identifier */) {
                        return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */);
                    }
                    break;
                }
            }
        }
        function bindPropertyWorker(node) {
            return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
        }
        function bindAnonymousTypeWorker(node) {
            return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type" /* Type */);
        }
        function checkTypePredicate(node) {
            var parameterName = node.parameterName, type = node.type;
            if (parameterName && parameterName.kind === 71 /* Identifier */) {
                checkStrictModeIdentifier(parameterName);
            }
            if (parameterName && parameterName.kind === 169 /* ThisType */) {
                seenThisKeyword = true;
            }
            bind(type);
        }
        function bindSourceFileIfExternalModule() {
            setExportContextFlag(file);
            if (ts.isExternalModule(file)) {
                bindSourceFileAsExternalModule();
            }
        }
        function bindSourceFileAsExternalModule() {
            bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
        }
        function bindExportAssignment(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export assignment in some sort of block construct
                bindAnonymousDeclaration(node, 2097152 /* Alias */, getDeclarationName(node));
            }
            else {
                // An export default clause with an expression exports a value
                // We want to exclude both class and function here,  this is necessary to issue an error when there are both
                // default export-assignment and default export function and class declaration.
                var flags = node.kind === 243 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node)
                    // An export default clause with an EntityNameExpression exports all meanings of that identifier
                    ? 2097152 /* Alias */
                    // An export default clause with any other expression exports a value
                    : 4 /* Property */;
                declareSymbol(container.symbol.exports, container.symbol, node, flags, 4 /* Property */ | 2097152 /* AliasExcludes */ | 32 /* Class */ | 16 /* Function */);
            }
        }
        function bindNamespaceExportDeclaration(node) {
            if (node.modifiers && node.modifiers.length) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here));
            }
            if (node.parent.kind !== 265 /* SourceFile */) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level));
                return;
            }
            else {
                var parent_1 = node.parent;
                if (!ts.isExternalModule(parent_1)) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files));
                    return;
                }
                if (!parent_1.isDeclarationFile) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files));
                    return;
                }
            }
            file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable();
            declareSymbol(file.symbol.globalExports, file.symbol, node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
        }
        function bindExportDeclaration(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export * in some sort of block construct
                bindAnonymousDeclaration(node, 8388608 /* ExportStar */, getDeclarationName(node));
            }
            else if (!node.exportClause) {
                // All export * declarations are collected in an __export symbol
                declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* ExportStar */, 0 /* None */);
            }
        }
        function bindImportClause(node) {
            if (node.name) {
                declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function setCommonJsModuleIndicator(node) {
            if (!file.commonJsModuleIndicator) {
                file.commonJsModuleIndicator = node;
                if (!file.externalModuleIndicator) {
                    bindSourceFileAsExternalModule();
                }
            }
        }
        function bindExportsPropertyAssignment(node) {
            // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
            // expression is the declaration
            setCommonJsModuleIndicator(node);
            declareSymbol(file.symbol.exports, file.symbol, node.left, 4 /* Property */ | 1048576 /* ExportValue */, 0 /* None */);
        }
        function isExportsOrModuleExportsOrAlias(node) {
            return ts.isExportsIdentifier(node) ||
                ts.isModuleExportsPropertyAccessExpression(node) ||
                ts.isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node);
        }
        function isNameOfExportsOrModuleExportsAliasDeclaration(node) {
            var symbol = lookupSymbolForName(node.escapedText);
            return symbol && symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) &&
                symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
        }
        function isExportsOrModuleExportsOrAliasOrAssignment(node) {
            return isExportsOrModuleExportsOrAlias(node) ||
                (ts.isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right)));
        }
        function bindModuleExportsAssignment(node) {
            // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
            // is still pointing to 'module.exports'.
            // We do not want to consider this as 'export=' since a module can have only one of these.
            // Similarly we do not want to treat 'module.exports = exports' as an 'export='.
            var assignedExpression = ts.getRightMostAssignedExpression(node.right);
            if (ts.isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
                // Mark it as a module in case there are no other exports in the file
                setCommonJsModuleIndicator(node);
                return;
            }
            // 'module.exports = expr' assignment
            setCommonJsModuleIndicator(node);
            declareSymbol(file.symbol.exports, file.symbol, node, 4 /* Property */ | 1048576 /* ExportValue */ | 512 /* ValueModule */, 0 /* None */);
        }
        function bindThisPropertyAssignment(node) {
            ts.Debug.assert(ts.isInJavaScriptFile(node));
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            switch (container.kind) {
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                    // Declare a 'member' if the container is an ES5 class or ES6 constructor
                    container.symbol.members = container.symbol.members || ts.createSymbolTable();
                    // It's acceptable for multiple 'this' assignments of the same identifier to occur
                    declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */);
                    break;
                case 152 /* Constructor */:
                case 149 /* PropertyDeclaration */:
                case 151 /* MethodDeclaration */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    // this.foo assignment in a JavaScript class
                    // Bind this property to the containing class
                    var containingClass = container.parent;
                    var symbolTable = ts.hasModifier(container, 32 /* Static */) ? containingClass.symbol.exports : containingClass.symbol.members;
                    declareSymbol(symbolTable, containingClass.symbol, node, 4 /* Property */, 0 /* None */, /*isReplaceableByMethod*/ true);
                    break;
            }
        }
        function bindPrototypePropertyAssignment(node) {
            // We saw a node of the form 'x.prototype.y = z'. Declare a 'member' y on x if x was a function.
            // Look up the function in the local scope, since prototype assignments should
            // follow the function declaration
            var leftSideOfAssignment = node.left;
            var classPrototype = leftSideOfAssignment.expression;
            var constructorFunction = classPrototype.expression;
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            leftSideOfAssignment.parent = node;
            constructorFunction.parent = classPrototype;
            classPrototype.parent = leftSideOfAssignment;
            bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true);
        }
        function bindStaticPropertyAssignment(node) {
            // We saw a node of the form 'x.y = z'. Declare a 'member' y on x if x was a function.
            // Look up the function in the local scope, since prototype assignments should
            // follow the function declaration
            var leftSideOfAssignment = node.left;
            var target = leftSideOfAssignment.expression;
            if (ts.isIdentifier(target)) {
                // Fix up parent pointers since we're going to use these nodes before we bind into them
                leftSideOfAssignment.parent = node;
                target.parent = leftSideOfAssignment;
                if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
                    // This can be an alias for the 'exports' or 'module.exports' names, e.g.
                    //    var util = module.exports;
                    //    util.property = function ...
                    bindExportsPropertyAssignment(node);
                }
                else {
                    bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
                }
            }
        }
        function lookupSymbolForName(name) {
            return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || (container.locals && container.locals.get(name));
        }
        function bindPropertyAssignment(functionName, propertyAccessExpression, isPrototypeProperty) {
            var targetSymbol = lookupSymbolForName(functionName);
            if (targetSymbol && ts.isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
                targetSymbol = targetSymbol.valueDeclaration.initializer.symbol;
            }
            if (!targetSymbol || !(targetSymbol.flags & (16 /* Function */ | 32 /* Class */))) {
                return;
            }
            // Set up the members collection if it doesn't exist already
            var symbolTable = isPrototypeProperty ?
                (targetSymbol.members || (targetSymbol.members = ts.createSymbolTable())) :
                (targetSymbol.exports || (targetSymbol.exports = ts.createSymbolTable()));
            // Declare the method/property
            declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, 4 /* Property */, 0 /* PropertyExcludes */);
        }
        function bindCallExpression(node) {
            // We're only inspecting call expressions to detect CommonJS modules, so we can skip
            // this check if we've already seen the module indicator
            if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ false)) {
                setCommonJsModuleIndicator(node);
            }
        }
        function bindClassLikeDeclaration(node) {
            if (node.kind === 229 /* ClassDeclaration */) {
                bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
            }
            else {
                var bindingName = node.name ? node.name.escapedText : "__class" /* Class */;
                bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
                // Add name of class expression into the map for semantic classifier
                if (node.name) {
                    classifiableNames.set(node.name.escapedText, true);
                }
            }
            var symbol = node.symbol;
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype', the
            // type of which is an instantiation of the class type with type Any supplied as a type
            // argument for each type parameter. It is an error to explicitly declare a static
            // property member with the name 'prototype'.
            //
            // Note: we check for this here because this class may be merging into a module.  The
            // module might have an exported variable called 'prototype'.  We can't allow that as
            // that would clash with the built-in 'prototype' for the class.
            var prototypeSymbol = createSymbol(4 /* Property */ | 4194304 /* Prototype */, "prototype");
            var symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
            if (symbolExport) {
                if (node.name) {
                    node.name.parent = node;
                }
                file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol)));
            }
            symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
            prototypeSymbol.parent = symbol;
        }
        function bindEnumDeclaration(node) {
            return ts.isConst(node)
                ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
                : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
        }
        function bindVariableDeclarationOrBindingElement(node) {
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (!ts.isBindingPattern(node.name)) {
                if (ts.isBlockOrCatchScoped(node)) {
                    bindBlockScopedVariableDeclaration(node);
                }
                else if (ts.isParameterDeclaration(node)) {
                    // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
                    // because its parent chain has already been set up, since parents are set before descending into children.
                    //
                    // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
                    // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
                    // For example:
                    //      function foo([a,a]) {} // Duplicate Identifier error
                    //      function bar(a,a) {}   // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
                    //                             // which correctly set excluded symbols
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */);
                }
            }
        }
        function bindParameter(node) {
            if (inStrictMode && !ts.isInAmbientContext(node)) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
                // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (ts.isBindingPattern(node.name)) {
                bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, "__" + ts.indexOf(node.parent.parameters, node));
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
            }
            // If this is a property-parameter, then also declare the property symbol into the
            // containing class.
            if (ts.isParameterPropertyDeclaration(node)) {
                var classDeclaration = node.parent.parent;
                declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
            }
        }
        function bindFunctionDeclaration(node) {
            if (!file.isDeclarationFile && !ts.isInAmbientContext(node)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 1024 /* HasAsyncFunctions */;
                }
            }
            checkStrictModeFunctionName(node);
            if (inStrictMode) {
                checkStrictModeFunctionDeclaration(node);
                bindBlockScopedDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */);
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
            }
        }
        function bindFunctionExpression(node) {
            if (!file.isDeclarationFile && !ts.isInAmbientContext(node)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 1024 /* HasAsyncFunctions */;
                }
            }
            if (currentFlow) {
                node.flowNode = currentFlow;
            }
            checkStrictModeFunctionName(node);
            var bindingName = node.name ? node.name.escapedText : "__function" /* Function */;
            return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
        }
        function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
            if (!file.isDeclarationFile && !ts.isInAmbientContext(node) && ts.isAsyncFunction(node)) {
                emitFlags |= 1024 /* HasAsyncFunctions */;
            }
            if (currentFlow && ts.isObjectLiteralOrClassExpressionMethod(node)) {
                node.flowNode = currentFlow;
            }
            return ts.hasDynamicName(node)
                ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */)
                : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        // reachability checks
        function shouldReportErrorOnModuleDeclaration(node) {
            var instanceState = getModuleInstanceState(node);
            return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums);
        }
        function checkUnreachable(node) {
            if (!(currentFlow.flags & 1 /* Unreachable */)) {
                return false;
            }
            if (currentFlow === unreachableFlow) {
                var reportError = 
                // report error on all statements except empty ones
                (ts.isStatementButNotDeclaration(node) && node.kind !== 209 /* EmptyStatement */) ||
                    // report error on class declarations
                    node.kind === 229 /* ClassDeclaration */ ||
                    // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
                    (node.kind === 233 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
                    // report error on regular enums and const enums if preserveConstEnums is set
                    (node.kind === 232 /* EnumDeclaration */ && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
                if (reportError) {
                    currentFlow = reportedUnreachableFlow;
                    // unreachable code is reported if
                    // - user has explicitly asked about it AND
                    // - statement is in not ambient context (statements in ambient context is already an error
                    //   so we should not report extras) AND
                    //   - node is not variable statement OR
                    //   - node is block scoped variable statement OR
                    //   - node is not block scoped variable statement and at least one variable declaration has initializer
                    //   Rationale: we don't want to report errors on non-initialized var's since they are hoisted
                    //   On the other side we do want to report errors on non-initialized 'lets' because of TDZ
                    var reportUnreachableCode = !options.allowUnreachableCode &&
                        !ts.isInAmbientContext(node) &&
                        (node.kind !== 208 /* VariableStatement */ ||
                            ts.getCombinedNodeFlags(node.declarationList) & 3 /* BlockScoped */ ||
                            ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
                    if (reportUnreachableCode) {
                        errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
                    }
                }
            }
            return true;
        }
    }
    /**
     * Computes the transform flags for a node, given the transform flags of its subtree
     *
     * @param node The node to analyze
     * @param subtreeFlags Transform flags computed for this node's subtree
     */
    function computeTransformFlagsForNode(node, subtreeFlags) {
        var kind = node.kind;
        switch (kind) {
            case 181 /* CallExpression */:
                return computeCallExpression(node, subtreeFlags);
            case 182 /* NewExpression */:
                return computeNewExpression(node, subtreeFlags);
            case 233 /* ModuleDeclaration */:
                return computeModuleDeclaration(node, subtreeFlags);
            case 185 /* ParenthesizedExpression */:
                return computeParenthesizedExpression(node, subtreeFlags);
            case 194 /* BinaryExpression */:
                return computeBinaryExpression(node, subtreeFlags);
            case 210 /* ExpressionStatement */:
                return computeExpressionStatement(node, subtreeFlags);
            case 146 /* Parameter */:
                return computeParameter(node, subtreeFlags);
            case 187 /* ArrowFunction */:
                return computeArrowFunction(node, subtreeFlags);
            case 186 /* FunctionExpression */:
                return computeFunctionExpression(node, subtreeFlags);
            case 228 /* FunctionDeclaration */:
                return computeFunctionDeclaration(node, subtreeFlags);
            case 226 /* VariableDeclaration */:
                return computeVariableDeclaration(node, subtreeFlags);
            case 227 /* VariableDeclarationList */:
                return computeVariableDeclarationList(node, subtreeFlags);
            case 208 /* VariableStatement */:
                return computeVariableStatement(node, subtreeFlags);
            case 222 /* LabeledStatement */:
                return computeLabeledStatement(node, subtreeFlags);
            case 229 /* ClassDeclaration */:
                return computeClassDeclaration(node, subtreeFlags);
            case 199 /* ClassExpression */:
                return computeClassExpression(node, subtreeFlags);
            case 259 /* HeritageClause */:
                return computeHeritageClause(node, subtreeFlags);
            case 260 /* CatchClause */:
                return computeCatchClause(node, subtreeFlags);
            case 201 /* ExpressionWithTypeArguments */:
                return computeExpressionWithTypeArguments(node, subtreeFlags);
            case 152 /* Constructor */:
                return computeConstructor(node, subtreeFlags);
            case 149 /* PropertyDeclaration */:
                return computePropertyDeclaration(node, subtreeFlags);
            case 151 /* MethodDeclaration */:
                return computeMethod(node, subtreeFlags);
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
                return computeAccessor(node, subtreeFlags);
            case 237 /* ImportEqualsDeclaration */:
                return computeImportEquals(node, subtreeFlags);
            case 179 /* PropertyAccessExpression */:
                return computePropertyAccess(node, subtreeFlags);
            default:
                return computeOther(node, kind, subtreeFlags);
        }
    }
    ts.computeTransformFlagsForNode = computeTransformFlagsForNode;
    function computeCallExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var expression = node.expression;
        var expressionKind = expression.kind;
        if (node.typeArguments) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        if (subtreeFlags & 524288 /* ContainsSpread */
            || isSuperOrSuperProperty(expression, expressionKind)) {
            // If the this node contains a SpreadExpression, or is a super call, then it is an ES6
            // node.
            transformFlags |= 192 /* AssertES2015 */;
        }
        if (expression.kind === 91 /* ImportKeyword */) {
            transformFlags |= 67108864 /* ContainsDynamicImport */;
            // A dynamic 'import()' call that contains a lexical 'this' will
            // require a captured 'this' when emitting down-level.
            if (subtreeFlags & 16384 /* ContainsLexicalThis */) {
                transformFlags |= 32768 /* ContainsCapturedLexicalThis */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537396545 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function isSuperOrSuperProperty(node, kind) {
        switch (kind) {
            case 97 /* SuperKeyword */:
                return true;
            case 179 /* PropertyAccessExpression */:
            case 180 /* ElementAccessExpression */:
                var expression = node.expression;
                var expressionKind = expression.kind;
                return expressionKind === 97 /* SuperKeyword */;
        }
        return false;
    }
    function computeNewExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.typeArguments) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        if (subtreeFlags & 524288 /* ContainsSpread */) {
            // If the this node contains a SpreadElementExpression then it is an ES6
            // node.
            transformFlags |= 192 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537396545 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeBinaryExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var operatorTokenKind = node.operatorToken.kind;
        var leftKind = node.left.kind;
        if (operatorTokenKind === 58 /* EqualsToken */ && leftKind === 178 /* ObjectLiteralExpression */) {
            // Destructuring object assignments with are ES2015 syntax
            // and possibly ESNext if they contain rest
            transformFlags |= 8 /* AssertESNext */ | 192 /* AssertES2015 */ | 3072 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 58 /* EqualsToken */ && leftKind === 177 /* ArrayLiteralExpression */) {
            // Destructuring assignments are ES2015 syntax.
            transformFlags |= 192 /* AssertES2015 */ | 3072 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 40 /* AsteriskAsteriskToken */
            || operatorTokenKind === 62 /* AsteriskAsteriskEqualsToken */) {
            // Exponentiation is ES2016 syntax.
            transformFlags |= 32 /* AssertES2016 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeParameter(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var name = node.name;
        var initializer = node.initializer;
        var dotDotDotToken = node.dotDotDotToken;
        // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
        // syntax.
        if (node.questionToken
            || node.type
            || subtreeFlags & 4096 /* ContainsDecorators */
            || ts.isThisIdentifier(name)) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // If a parameter has an accessibility modifier, then it is TypeScript syntax.
        if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
            transformFlags |= 3 /* AssertTypeScript */ | 262144 /* ContainsParameterPropertyAssignments */;
        }
        // parameters with object rest destructuring are ES Next syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        // If a parameter has an initializer, a binding pattern or a dotDotDot token, then
        // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
        if (subtreeFlags & 8388608 /* ContainsBindingPattern */ || initializer || dotDotDotToken) {
            transformFlags |= 192 /* AssertES2015 */ | 131072 /* ContainsDefaultValueAssignments */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* ParameterExcludes */;
    }
    function computeParenthesizedExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var expression = node.expression;
        var expressionKind = expression.kind;
        var expressionTransformFlags = expression.transformFlags;
        // If the node is synthesized, it means the emitter put the parentheses there,
        // not the user. If we didn't want them, the emitter would not have put them
        // there.
        if (expressionKind === 202 /* AsExpression */
            || expressionKind === 184 /* TypeAssertionExpression */) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // If the expression of a ParenthesizedExpression is a destructuring assignment,
        // then the ParenthesizedExpression is a destructuring assignment.
        if (expressionTransformFlags & 1024 /* DestructuringAssignment */) {
            transformFlags |= 1024 /* DestructuringAssignment */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeClassDeclaration(node, subtreeFlags) {
        var transformFlags;
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            transformFlags = 3 /* AssertTypeScript */;
        }
        else {
            // A ClassDeclaration is ES6 syntax.
            transformFlags = subtreeFlags | 192 /* AssertES2015 */;
            // A class with a parameter property assignment, property initializer, or decorator is
            // TypeScript syntax.
            // An exported declaration may be TypeScript syntax, but is handled by the visitor
            // for a namespace declaration.
            if ((subtreeFlags & 274432 /* TypeScriptClassSyntaxMask */)
                || node.typeParameters) {
                transformFlags |= 3 /* AssertTypeScript */;
            }
            if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) {
                // A computed property name containing `this` might need to be rewritten,
                // so propagate the ContainsLexicalThis flag upward.
                transformFlags |= 16384 /* ContainsLexicalThis */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~539358529 /* ClassExcludes */;
    }
    function computeClassExpression(node, subtreeFlags) {
        // A ClassExpression is ES6 syntax.
        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
        // A class with a parameter property assignment, property initializer, or decorator is
        // TypeScript syntax.
        if (subtreeFlags & 274432 /* TypeScriptClassSyntaxMask */
            || node.typeParameters) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) {
            // A computed property name containing `this` might need to be rewritten,
            // so propagate the ContainsLexicalThis flag upward.
            transformFlags |= 16384 /* ContainsLexicalThis */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~539358529 /* ClassExcludes */;
    }
    function computeHeritageClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        switch (node.token) {
            case 85 /* ExtendsKeyword */:
                // An `extends` HeritageClause is ES6 syntax.
                transformFlags |= 192 /* AssertES2015 */;
                break;
            case 108 /* ImplementsKeyword */:
                // An `implements` HeritageClause is TypeScript syntax.
                transformFlags |= 3 /* AssertTypeScript */;
                break;
            default:
                ts.Debug.fail("Unexpected token for heritage clause");
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeCatchClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (!node.variableDeclaration) {
            transformFlags |= 8 /* AssertESNext */;
        }
        else if (ts.isBindingPattern(node.variableDeclaration.name)) {
            transformFlags |= 192 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537920833 /* CatchClauseExcludes */;
    }
    function computeExpressionWithTypeArguments(node, subtreeFlags) {
        // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
        // extends clause of a class.
        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
        // If an ExpressionWithTypeArguments contains type arguments, then it
        // is TypeScript syntax.
        if (node.typeArguments) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeConstructor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers and overloads are TypeScript syntax
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || !node.body) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES Next syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~601015617 /* ConstructorExcludes */;
    }
    function computeMethod(node, subtreeFlags) {
        // A MethodDeclaration is ES6 syntax.
        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
        // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
        // overloads are TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type
            || !node.body) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES Next syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        // An async method declaration is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */;
        }
        if (node.asteriskToken) {
            transformFlags |= 768 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~601015617 /* MethodOrAccessorExcludes */;
    }
    function computeAccessor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // Decorators, TypeScript-specific modifiers, type annotations, and overloads are
        // TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.type
            || !node.body) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES Next syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~601015617 /* MethodOrAccessorExcludes */;
    }
    function computePropertyDeclaration(node, subtreeFlags) {
        // A PropertyDeclaration is TypeScript syntax.
        var transformFlags = subtreeFlags | 3 /* AssertTypeScript */;
        // If the PropertyDeclaration has an initializer, we need to inform its ancestor
        // so that it handle the transformation.
        if (node.initializer) {
            transformFlags |= 8192 /* ContainsPropertyInitializer */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeFunctionDeclaration(node, subtreeFlags) {
        var transformFlags;
        var modifierFlags = ts.getModifierFlags(node);
        var body = node.body;
        if (!body || (modifierFlags & 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            // A FunctionDeclaration without a body is an overload and is TypeScript syntax.
            transformFlags = 3 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags | 33554432 /* ContainsHoistedDeclarationOrCompletion */;
            // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
            // syntax.
            if (modifierFlags & 2270 /* TypeScriptModifier */
                || node.typeParameters
                || node.type) {
                transformFlags |= 3 /* AssertTypeScript */;
            }
            // An async function declaration is ES2017 syntax.
            if (modifierFlags & 256 /* Async */) {
                transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */;
            }
            // function declarations with object rest destructuring are ES Next syntax
            if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
                transformFlags |= 8 /* AssertESNext */;
            }
            // If a FunctionDeclaration's subtree has marked the container as needing to capture the
            // lexical this, or the function contains parameters with initializers, then this node is
            // ES6 syntax.
            if (subtreeFlags & 163840 /* ES2015FunctionSyntaxMask */) {
                transformFlags |= 192 /* AssertES2015 */;
            }
            // If a FunctionDeclaration is generator function and is the body of a
            // transformed async function, then this node can be transformed to a
            // down-level generator.
            // Currently we do not support transforming any other generator fucntions
            // down level.
            if (node.asteriskToken) {
                transformFlags |= 768 /* AssertGenerator */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~601281857 /* FunctionExcludes */;
    }
    function computeFunctionExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // An async function expression is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */;
        }
        // function expressions with object rest destructuring are ES Next syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        // If a FunctionExpression's subtree has marked the container as needing to capture the
        // lexical this, or the function contains parameters with initializers, then this node is
        // ES6 syntax.
        if (subtreeFlags & 163840 /* ES2015FunctionSyntaxMask */) {
            transformFlags |= 192 /* AssertES2015 */;
        }
        // If a FunctionExpression is generator function and is the body of a
        // transformed async function, then this node can be transformed to a
        // down-level generator.
        if (node.asteriskToken) {
            transformFlags |= 768 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~601281857 /* FunctionExcludes */;
    }
    function computeArrowFunction(node, subtreeFlags) {
        // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
        var transformFlags = subtreeFlags | 192 /* AssertES2015 */;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        // An async arrow function is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= 16 /* AssertES2017 */;
        }
        // arrow functions with object rest destructuring are ES Next syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        // If an ArrowFunction contains a lexical this, its container must capture the lexical this.
        if (subtreeFlags & 16384 /* ContainsLexicalThis */) {
            transformFlags |= 32768 /* ContainsCapturedLexicalThis */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~601249089 /* ArrowFunctionExcludes */;
    }
    function computePropertyAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var expression = node.expression;
        var expressionKind = expression.kind;
        // If a PropertyAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (expressionKind === 97 /* SuperKeyword */) {
            transformFlags |= 16384 /* ContainsLexicalThis */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeVariableDeclaration(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */;
        // A VariableDeclaration containing ObjectRest is ESNext syntax
        if (subtreeFlags & 1048576 /* ContainsObjectRest */) {
            transformFlags |= 8 /* AssertESNext */;
        }
        // Type annotations are TypeScript syntax.
        if (node.type) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeVariableStatement(node, subtreeFlags) {
        var transformFlags;
        var declarationListTransformFlags = node.declarationList.transformFlags;
        // An ambient declaration is TypeScript syntax.
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            transformFlags = 3 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags;
            if (declarationListTransformFlags & 8388608 /* ContainsBindingPattern */) {
                transformFlags |= 192 /* AssertES2015 */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeLabeledStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
        if (subtreeFlags & 4194304 /* ContainsBlockScopedBinding */
            && ts.isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
            transformFlags |= 192 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeImportEquals(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // An ImportEqualsDeclaration with a namespace reference is TypeScript.
        if (!ts.isExternalModuleImportEqualsDeclaration(node)) {
            transformFlags |= 3 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeExpressionStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // If the expression of an expression statement is a destructuring assignment,
        // then we treat the statement as ES6 so that we can indicate that we do not
        // need to hold on to the right-hand side.
        if (node.expression.transformFlags & 1024 /* DestructuringAssignment */) {
            transformFlags |= 192 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536872257 /* NodeExcludes */;
    }
    function computeModuleDeclaration(node, subtreeFlags) {
        var transformFlags = 3 /* AssertTypeScript */;
        var modifierFlags = ts.getModifierFlags(node);
        if ((modifierFlags & 2 /* Ambient */) === 0) {
            transformFlags |= subtreeFlags;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~574674241 /* ModuleExcludes */;
    }
    function computeVariableDeclarationList(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 33554432 /* ContainsHoistedDeclarationOrCompletion */;
        if (subtreeFlags & 8388608 /* ContainsBindingPattern */) {
            transformFlags |= 192 /* AssertES2015 */;
        }
        // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
        if (node.flags & 3 /* BlockScoped */) {
            transformFlags |= 192 /* AssertES2015 */ | 4194304 /* ContainsBlockScopedBinding */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~546309441 /* VariableDeclarationListExcludes */;
    }
    function computeOther(node, kind, subtreeFlags) {
        // Mark transformations needed for each node
        var transformFlags = subtreeFlags;
        var excludeFlags = 536872257 /* NodeExcludes */;
        switch (kind) {
            case 120 /* AsyncKeyword */:
            case 191 /* AwaitExpression */:
                // async/await is ES2017 syntax, but may be ESNext syntax (for async generators)
                transformFlags |= 8 /* AssertESNext */ | 16 /* AssertES2017 */;
                break;
            case 114 /* PublicKeyword */:
            case 112 /* PrivateKeyword */:
            case 113 /* ProtectedKeyword */:
            case 117 /* AbstractKeyword */:
            case 124 /* DeclareKeyword */:
            case 76 /* ConstKeyword */:
            case 232 /* EnumDeclaration */:
            case 264 /* EnumMember */:
            case 184 /* TypeAssertionExpression */:
            case 202 /* AsExpression */:
            case 203 /* NonNullExpression */:
            case 131 /* ReadonlyKeyword */:
                // These nodes are TypeScript syntax.
                transformFlags |= 3 /* AssertTypeScript */;
                break;
            case 249 /* JsxElement */:
            case 250 /* JsxSelfClosingElement */:
            case 251 /* JsxOpeningElement */:
            case 10 /* JsxText */:
            case 252 /* JsxClosingElement */:
            case 253 /* JsxAttribute */:
            case 254 /* JsxAttributes */:
            case 255 /* JsxSpreadAttribute */:
            case 256 /* JsxExpression */:
                // These nodes are Jsx syntax.
                transformFlags |= 4 /* AssertJsx */;
                break;
            case 13 /* NoSubstitutionTemplateLiteral */:
            case 14 /* TemplateHead */:
            case 15 /* TemplateMiddle */:
            case 16 /* TemplateTail */:
            case 196 /* TemplateExpression */:
            case 183 /* TaggedTemplateExpression */:
            case 262 /* ShorthandPropertyAssignment */:
            case 115 /* StaticKeyword */:
            case 204 /* MetaProperty */:
                // These nodes are ES6 syntax.
                transformFlags |= 192 /* AssertES2015 */;
                break;
            case 9 /* StringLiteral */:
                if (node.hasExtendedUnicodeEscape) {
                    transformFlags |= 192 /* AssertES2015 */;
                }
                break;
            case 8 /* NumericLiteral */:
                if (node.numericLiteralFlags & 48 /* BinaryOrOctalSpecifier */) {
                    transformFlags |= 192 /* AssertES2015 */;
                }
                break;
            case 216 /* ForOfStatement */:
                // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
                if (node.awaitModifier) {
                    transformFlags |= 8 /* AssertESNext */;
                }
                transformFlags |= 192 /* AssertES2015 */;
                break;
            case 197 /* YieldExpression */:
                // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
                // generator).
                transformFlags |= 8 /* AssertESNext */ | 192 /* AssertES2015 */ | 16777216 /* ContainsYield */;
                break;
            case 119 /* AnyKeyword */:
            case 133 /* NumberKeyword */:
            case 130 /* NeverKeyword */:
            case 134 /* ObjectKeyword */:
            case 136 /* StringKeyword */:
            case 122 /* BooleanKeyword */:
            case 137 /* SymbolKeyword */:
            case 105 /* VoidKeyword */:
            case 145 /* TypeParameter */:
            case 148 /* PropertySignature */:
            case 150 /* MethodSignature */:
            case 155 /* CallSignature */:
            case 156 /* ConstructSignature */:
            case 157 /* IndexSignature */:
            case 158 /* TypePredicate */:
            case 159 /* TypeReference */:
            case 160 /* FunctionType */:
            case 161 /* ConstructorType */:
            case 162 /* TypeQuery */:
            case 163 /* TypeLiteral */:
            case 164 /* ArrayType */:
            case 165 /* TupleType */:
            case 166 /* UnionType */:
            case 167 /* IntersectionType */:
            case 168 /* ParenthesizedType */:
            case 230 /* InterfaceDeclaration */:
            case 231 /* TypeAliasDeclaration */:
            case 169 /* ThisType */:
            case 170 /* TypeOperator */:
            case 171 /* IndexedAccessType */:
            case 172 /* MappedType */:
            case 173 /* LiteralType */:
            case 236 /* NamespaceExportDeclaration */:
                // Types and signatures are TypeScript syntax, and exclude all other facts.
                transformFlags = 3 /* AssertTypeScript */;
                excludeFlags = -3 /* TypeExcludes */;
                break;
            case 144 /* ComputedPropertyName */:
                // Even though computed property names are ES6, we don't treat them as such.
                // This is so that they can flow through PropertyName transforms unaffected.
                // Instead, we mark the container as ES6, so that it can properly handle the transform.
                transformFlags |= 2097152 /* ContainsComputedPropertyName */;
                if (subtreeFlags & 16384 /* ContainsLexicalThis */) {
                    // A computed method name like `[this.getName()](x: string) { ... }` needs to
                    // distinguish itself from the normal case of a method body containing `this`:
                    // `this` inside a method doesn't need to be rewritten (the method provides `this`),
                    // whereas `this` inside a computed name *might* need to be rewritten if the class/object
                    // is inside an arrow function:
                    // `_this = this; () => class K { [_this.getName()]() { ... } }`
                    // To make this distinction, use ContainsLexicalThisInComputedPropertyName
                    // instead of ContainsLexicalThis for computed property names
                    transformFlags |= 65536 /* ContainsLexicalThisInComputedPropertyName */;
                }
                break;
            case 198 /* SpreadElement */:
                transformFlags |= 192 /* AssertES2015 */ | 524288 /* ContainsSpread */;
                break;
            case 263 /* SpreadAssignment */:
                transformFlags |= 8 /* AssertESNext */ | 1048576 /* ContainsObjectSpread */;
                break;
            case 97 /* SuperKeyword */:
                // This node is ES6 syntax.
                transformFlags |= 192 /* AssertES2015 */;
                break;
            case 99 /* ThisKeyword */:
                // Mark this node and its ancestors as containing a lexical `this` keyword.
                transformFlags |= 16384 /* ContainsLexicalThis */;
                break;
            case 174 /* ObjectBindingPattern */:
                transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */;
                if (subtreeFlags & 524288 /* ContainsRest */) {
                    transformFlags |= 8 /* AssertESNext */ | 1048576 /* ContainsObjectRest */;
                }
                excludeFlags = 537396545 /* BindingPatternExcludes */;
                break;
            case 175 /* ArrayBindingPattern */:
                transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */;
                excludeFlags = 537396545 /* BindingPatternExcludes */;
                break;
            case 176 /* BindingElement */:
                transformFlags |= 192 /* AssertES2015 */;
                if (node.dotDotDotToken) {
                    transformFlags |= 524288 /* ContainsRest */;
                }
                break;
            case 147 /* Decorator */:
                // This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
                transformFlags |= 3 /* AssertTypeScript */ | 4096 /* ContainsDecorators */;
                break;
            case 178 /* ObjectLiteralExpression */:
                excludeFlags = 540087617 /* ObjectLiteralExcludes */;
                if (subtreeFlags & 2097152 /* ContainsComputedPropertyName */) {
                    // If an ObjectLiteralExpression contains a ComputedPropertyName, then it
                    // is an ES6 node.
                    transformFlags |= 192 /* AssertES2015 */;
                }
                if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) {
                    // A computed property name containing `this` might need to be rewritten,
                    // so propagate the ContainsLexicalThis flag upward.
                    transformFlags |= 16384 /* ContainsLexicalThis */;
                }
                if (subtreeFlags & 1048576 /* ContainsObjectSpread */) {
                    // If an ObjectLiteralExpression contains a spread element, then it
                    // is an ES next node.
                    transformFlags |= 8 /* AssertESNext */;
                }
                break;
            case 177 /* ArrayLiteralExpression */:
            case 182 /* NewExpression */:
                excludeFlags = 537396545 /* ArrayLiteralOrCallOrNewExcludes */;
                if (subtreeFlags & 524288 /* ContainsSpread */) {
                    // If the this node contains a SpreadExpression, then it is an ES6
                    // node.
                    transformFlags |= 192 /* AssertES2015 */;
                }
                break;
            case 212 /* DoStatement */:
            case 213 /* WhileStatement */:
            case 214 /* ForStatement */:
            case 215 /* ForInStatement */:
                // A loop containing a block scoped binding *may* need to be transformed from ES6.
                if (subtreeFlags & 4194304 /* ContainsBlockScopedBinding */) {
                    transformFlags |= 192 /* AssertES2015 */;
                }
                break;
            case 265 /* SourceFile */:
                if (subtreeFlags & 32768 /* ContainsCapturedLexicalThis */) {
                    transformFlags |= 192 /* AssertES2015 */;
                }
                break;
            case 219 /* ReturnStatement */:
            case 217 /* ContinueStatement */:
            case 218 /* BreakStatement */:
                transformFlags |= 33554432 /* ContainsHoistedDeclarationOrCompletion */;
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~excludeFlags;
    }
    /**
     * Gets the transform flags to exclude when unioning the transform flags of a subtree.
     *
     * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
     *       For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
     *       than calling this function.
     */
    /* @internal */
    function getTransformFlagsSubtreeExclusions(kind) {
        if (kind >= 158 /* FirstTypeNode */ && kind <= 173 /* LastTypeNode */) {
            return -3 /* TypeExcludes */;
        }
        switch (kind) {
            case 181 /* CallExpression */:
            case 182 /* NewExpression */:
            case 177 /* ArrayLiteralExpression */:
                return 537396545 /* ArrayLiteralOrCallOrNewExcludes */;
            case 233 /* ModuleDeclaration */:
                return 574674241 /* ModuleExcludes */;
            case 146 /* Parameter */:
                return 536872257 /* ParameterExcludes */;
            case 187 /* ArrowFunction */:
                return 601249089 /* ArrowFunctionExcludes */;
            case 186 /* FunctionExpression */:
            case 228 /* FunctionDeclaration */:
                return 601281857 /* FunctionExcludes */;
            case 227 /* VariableDeclarationList */:
                return 546309441 /* VariableDeclarationListExcludes */;
            case 229 /* ClassDeclaration */:
            case 199 /* ClassExpression */:
                return 539358529 /* ClassExcludes */;
            case 152 /* Constructor */:
                return 601015617 /* ConstructorExcludes */;
            case 151 /* MethodDeclaration */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
                return 601015617 /* MethodOrAccessorExcludes */;
            case 119 /* AnyKeyword */:
            case 133 /* NumberKeyword */:
            case 130 /* NeverKeyword */:
            case 136 /* StringKeyword */:
            case 134 /* ObjectKeyword */:
            case 122 /* BooleanKeyword */:
            case 137 /* SymbolKeyword */:
            case 105 /* VoidKeyword */:
            case 145 /* TypeParameter */:
            case 148 /* PropertySignature */:
            case 150 /* MethodSignature */:
            case 155 /* CallSignature */:
            case 156 /* ConstructSignature */:
            case 157 /* IndexSignature */:
            case 230 /* InterfaceDeclaration */:
            case 231 /* TypeAliasDeclaration */:
                return -3 /* TypeExcludes */;
            case 178 /* ObjectLiteralExpression */:
                return 540087617 /* ObjectLiteralExcludes */;
            case 260 /* CatchClause */:
                return 537920833 /* CatchClauseExcludes */;
            case 174 /* ObjectBindingPattern */:
            case 175 /* ArrayBindingPattern */:
                return 537396545 /* BindingPatternExcludes */;
            default:
                return 536872257 /* NodeExcludes */;
        }
    }
    ts.getTransformFlagsSubtreeExclusions = getTransformFlagsSubtreeExclusions;
    /**
     * "Binds" JSDoc nodes in TypeScript code.
     * Since we will never create symbols for JSDoc, we just set parent pointers instead.
     */
    function setParentPointers(parent, child) {
        child.parent = parent;
        ts.forEachChild(child, function (childsChild) { return setParentPointers(child, childsChild); });
    }
})(ts || (ts = {}));
/** @internal */
var ts;
(function (ts) {
    function createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier) {
        return getSymbolWalker;
        function getSymbolWalker(accept) {
            if (accept === void 0) { accept = function () { return true; }; }
            var visitedTypes = []; // Sparse array from id to type
            var visitedSymbols = []; // Sparse array from id to symbol
            return {
                walkType: function (type) {
                    try {
                        visitType(type);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
                walkSymbol: function (symbol) {
                    try {
                        visitSymbol(symbol);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
            };
            function visitType(type) {
                if (!type) {
                    return;
                }
                if (visitedTypes[type.id]) {
                    return;
                }
                visitedTypes[type.id] = type;
                // Reuse visitSymbol to visit the type's symbol,
                //  but be sure to bail on recuring into the type if accept declines the symbol.
                var shouldBail = visitSymbol(type.symbol);
                if (shouldBail)
                    return;
                // Visit the type's related types, if any
                if (type.flags & 32768 /* Object */) {
                    var objectType = type;
                    var objectFlags = objectType.objectFlags;
                    if (objectFlags & 4 /* Reference */) {
                        visitTypeReference(type);
                    }
                    if (objectFlags & 32 /* Mapped */) {
                        visitMappedType(type);
                    }
                    if (objectFlags & (1 /* Class */ | 2 /* Interface */)) {
                        visitInterfaceType(type);
                    }
                    if (objectFlags & (8 /* Tuple */ | 16 /* Anonymous */)) {
                        visitObjectType(objectType);
                    }
                }
                if (type.flags & 16384 /* TypeParameter */) {
                    visitTypeParameter(type);
                }
                if (type.flags & 196608 /* UnionOrIntersection */) {
                    visitUnionOrIntersectionType(type);
                }
                if (type.flags & 262144 /* Index */) {
                    visitIndexType(type);
                }
                if (type.flags & 524288 /* IndexedAccess */) {
                    visitIndexedAccessType(type);
                }
            }
            function visitTypeReference(type) {
                visitType(type.target);
                ts.forEach(type.typeArguments, visitType);
            }
            function visitTypeParameter(type) {
                visitType(getConstraintFromTypeParameter(type));
            }
            function visitUnionOrIntersectionType(type) {
                ts.forEach(type.types, visitType);
            }
            function visitIndexType(type) {
                visitType(type.type);
            }
            function visitIndexedAccessType(type) {
                visitType(type.objectType);
                visitType(type.indexType);
                visitType(type.constraint);
            }
            function visitMappedType(type) {
                visitType(type.typeParameter);
                visitType(type.constraintType);
                visitType(type.templateType);
                visitType(type.modifiersType);
            }
            function visitSignature(signature) {
                if (signature.typePredicate) {
                    visitType(signature.typePredicate.type);
                }
                ts.forEach(signature.typeParameters, visitType);
                for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
                    var parameter = _a[_i];
                    visitSymbol(parameter);
                }
                visitType(getRestTypeOfSignature(signature));
                visitType(getReturnTypeOfSignature(signature));
            }
            function visitInterfaceType(interfaceT) {
                visitObjectType(interfaceT);
                ts.forEach(interfaceT.typeParameters, visitType);
                ts.forEach(getBaseTypes(interfaceT), visitType);
                visitType(interfaceT.thisType);
            }
            function visitObjectType(type) {
                var stringIndexType = getIndexTypeOfStructuredType(type, 0 /* String */);
                visitType(stringIndexType);
                var numberIndexType = getIndexTypeOfStructuredType(type, 1 /* Number */);
                visitType(numberIndexType);
                // The two checks above *should* have already resolved the type (if needed), so this should be cached
                var resolved = resolveStructuredTypeMembers(type);
                for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    visitSignature(signature);
                }
                for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
                    var signature = _c[_b];
                    visitSignature(signature);
                }
                for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
                    var p = _e[_d];
                    visitSymbol(p);
                }
            }
            function visitSymbol(symbol) {
                if (!symbol) {
                    return;
                }
                var symbolId = ts.getSymbolId(symbol);
                if (visitedSymbols[symbolId]) {
                    return;
                }
                visitedSymbols[symbolId] = symbol;
                if (!accept(symbol)) {
                    return true;
                }
                var t = getTypeOfSymbol(symbol);
                visitType(t); // Should handle members on classes and such
                if (symbol.flags & 1952 /* HasExports */) {
                    symbol.exports.forEach(visitSymbol);
                }
                ts.forEach(symbol.declarations, function (d) {
                    // Type queries are too far resolved when we just visit the symbol's type
                    //  (their type resolved directly to the member deeply referenced)
                    // So to get the intervening symbols, we need to check if there's a type
                    // query node on any of the symbol's declarations and get symbols there
                    if (d.type && d.type.kind === 162 /* TypeQuery */) {
                        var query = d.type;
                        var entity = getResolvedSymbol(getFirstIdentifier(query.exprName));
                        visitSymbol(entity);
                    }
                });
            }
        }
    }
    ts.createGetSymbolWalker = createGetSymbolWalker;
})(ts || (ts = {}));
/// <reference path="core.ts" />
/// <reference path="diagnosticInformationMap.generated.ts" />
var ts;
(function (ts) {
    function trace(host) {
        host.trace(ts.formatMessage.apply(undefined, arguments));
    }
    ts.trace = trace;
    /* @internal */
    function isTraceEnabled(compilerOptions, host) {
        return compilerOptions.traceResolution && host.trace !== undefined;
    }
    ts.isTraceEnabled = isTraceEnabled;
    function withPackageId(packageId, r) {
        return r && { path: r.path, extension: r.ext, packageId: packageId };
    }
    function noPackageId(r) {
        return withPackageId(/*packageId*/ undefined, r);
    }
    /**
     * Kinds of file that we are currently looking for.
     * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
     */
    var Extensions;
    (function (Extensions) {
        Extensions[Extensions["TypeScript"] = 0] = "TypeScript";
        Extensions[Extensions["JavaScript"] = 1] = "JavaScript";
        Extensions[Extensions["DtsOnly"] = 2] = "DtsOnly"; /** Only '.d.ts' */
    })(Extensions || (Extensions = {}));
    /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
    function resolvedTypeScriptOnly(resolved) {
        if (!resolved) {
            return undefined;
        }
        ts.Debug.assert(ts.extensionIsTypeScript(resolved.extension));
        return { fileName: resolved.path, packageId: resolved.packageId };
    }
    function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) {
        return {
            resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId },
            failedLookupLocations: failedLookupLocations
        };
    }
    /** Reads from "main" or "types"/"typings" depending on `extensions`. */
    function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) {
        return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main");
        function tryReadFromField(fieldName) {
            if (!ts.hasProperty(jsonContent, fieldName)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName);
                }
                return;
            }
            var fileName = jsonContent[fieldName];
            if (!ts.isString(fileName)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName);
                }
                return;
            }
            var path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName));
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
            }
            return path;
        }
    }
    function readJson(path, host) {
        try {
            var jsonText = host.readFile(path);
            return jsonText ? JSON.parse(jsonText) : {};
        }
        catch (e) {
            // gracefully handle if readFile fails or returns not JSON
            return {};
        }
    }
    function getEffectiveTypeRoots(options, host) {
        if (options.typeRoots) {
            return options.typeRoots;
        }
        var currentDirectory;
        if (options.configFilePath) {
            currentDirectory = ts.getDirectoryPath(options.configFilePath);
        }
        else if (host.getCurrentDirectory) {
            currentDirectory = host.getCurrentDirectory();
        }
        if (currentDirectory !== undefined) {
            return getDefaultTypeRoots(currentDirectory, host);
        }
    }
    ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
    /**
     * Returns the path to every node_modules/@types directory from some ancestor directory.
     * Returns undefined if there are none.
     */
    function getDefaultTypeRoots(currentDirectory, host) {
        if (!host.directoryExists) {
            return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
            // And if it doesn't exist, tough.
        }
        var typeRoots;
        ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
            var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
            if (host.directoryExists(atTypes)) {
                (typeRoots || (typeRoots = [])).push(atTypes);
            }
            return undefined;
        });
        return typeRoots;
    }
    var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
    /**
     * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
     * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
     * is assumed to be the same as root directory of the project.
     */
    function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host) {
        var traceEnabled = isTraceEnabled(options, host);
        var moduleResolutionState = { compilerOptions: options, host: host, traceEnabled: traceEnabled };
        var typeRoots = getEffectiveTypeRoots(options, host);
        if (traceEnabled) {
            if (containingFile === undefined) {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots);
                }
            }
            else {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
                }
            }
        }
        var failedLookupLocations = [];
        var resolved = primaryLookup();
        var primary = true;
        if (!resolved) {
            resolved = secondaryLookup();
            primary = false;
        }
        var resolvedTypeReferenceDirective;
        if (resolved) {
            if (!options.preserveSymlinks) {
                resolved = __assign({}, resolved, { fileName: realPath(resolved.fileName, host, traceEnabled) });
            }
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary);
            }
            resolvedTypeReferenceDirective = { primary: primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId };
        }
        return { resolvedTypeReferenceDirective: resolvedTypeReferenceDirective, failedLookupLocations: failedLookupLocations };
        function primaryLookup() {
            // Check primary library paths
            if (typeRoots && typeRoots.length) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
                }
                return ts.forEach(typeRoots, function (typeRoot) {
                    var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName);
                    var candidateDirectory = ts.getDirectoryPath(candidate);
                    var directoryExists = directoryProbablyExists(candidateDirectory, host);
                    if (!directoryExists && traceEnabled) {
                        trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory);
                    }
                    return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations, !directoryExists, moduleResolutionState));
                });
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
                }
            }
        }
        function secondaryLookup() {
            var resolvedFile;
            var initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile);
            if (initialLocationForSecondaryLookup !== undefined) {
                // check secondary locations
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
                }
                var result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined);
                resolvedFile = resolvedTypeScriptOnly(result && result.value);
                if (!resolvedFile && traceEnabled) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
                }
                return resolvedFile;
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder);
                }
            }
        }
    }
    ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective;
    /**
     * Given a set of options, returns the set of type directive names
     *   that should be included for this program automatically.
     * This list could either come from the config file,
     *   or from enumerating the types root + initial secondary types lookup location.
     * More type directives might appear in the program later as a result of loading actual source files;
     *   this list is only the set of defaults that are implicitly included.
     */
    function getAutomaticTypeDirectiveNames(options, host) {
        // Use explicit type list from tsconfig.json
        if (options.types) {
            return options.types;
        }
        // Walk the primary type lookup locations
        var result = [];
        if (host.directoryExists && host.getDirectories) {
            var typeRoots = getEffectiveTypeRoots(options, host);
            if (typeRoots) {
                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
                    var root = typeRoots_1[_i];
                    if (host.directoryExists(root)) {
                        for (var _a = 0, _b = host.getDirectories(root); _a < _b.length; _a++) {
                            var typeDirectivePath = _b[_a];
                            var normalized = ts.normalizePath(typeDirectivePath);
                            var packageJsonPath = pathToPackageJson(ts.combinePaths(root, normalized));
                            // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
                            // See `createNotNeededPackageJSON` in the types-publisher` repo.
                            // tslint:disable-next-line:no-null-keyword
                            var isNotNeededPackage = host.fileExists(packageJsonPath) && readJson(packageJsonPath, host).typings === null;
                            if (!isNotNeededPackage) {
                                // Return just the type directive names
                                result.push(ts.getBaseFileName(normalized));
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
    ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames;
    function createModuleResolutionCache(currentDirectory, getCanonicalFileName) {
        var directoryToModuleNameMap = ts.createMap();
        var moduleNameToDirectoryMap = ts.createMap();
        return { getOrCreateCacheForDirectory: getOrCreateCacheForDirectory, getOrCreateCacheForModuleName: getOrCreateCacheForModuleName };
        function getOrCreateCacheForDirectory(directoryName) {
            var path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName);
            var perFolderCache = directoryToModuleNameMap.get(path);
            if (!perFolderCache) {
                perFolderCache = ts.createMap();
                directoryToModuleNameMap.set(path, perFolderCache);
            }
            return perFolderCache;
        }
        function getOrCreateCacheForModuleName(nonRelativeModuleName) {
            if (ts.isExternalModuleNameRelative(nonRelativeModuleName)) {
                return undefined;
            }
            var perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
            if (!perModuleNameCache) {
                perModuleNameCache = createPerModuleNameCache();
                moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache);
            }
            return perModuleNameCache;
        }
        function createPerModuleNameCache() {
            var directoryPathMap = ts.createMap();
            return { get: get, set: set };
            function get(directory) {
                return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName));
            }
            /**
             * At first this function add entry directory -> module resolution result to the table.
             * Then it computes the set of parent folders for 'directory' that should have the same module resolution result
             * and for every parent folder in set it adds entry: parent -> module resolution. .
             * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
             * Set of parent folders that should have the same result will be:
             * [
             *     /a/b/c/d, /a/b/c, /a/b
             * ]
             * this means that request for module resolution from file in any of these folder will be immediately found in cache.
             */
            function set(directory, result) {
                var path = ts.toPath(directory, currentDirectory, getCanonicalFileName);
                // if entry is already in cache do nothing
                if (directoryPathMap.has(path)) {
                    return;
                }
                directoryPathMap.set(path, result);
                var resolvedFileName = result.resolvedModule && result.resolvedModule.resolvedFileName;
                // find common prefix between directory and resolved file name
                // this common prefix should be the shorted path that has the same resolution
                // directory: /a/b/c/d/e
                // resolvedFileName: /a/b/foo.d.ts
                var commonPrefix = getCommonPrefix(path, resolvedFileName);
                var current = path;
                while (true) {
                    var parent = ts.getDirectoryPath(current);
                    if (parent === current || directoryPathMap.has(parent)) {
                        break;
                    }
                    directoryPathMap.set(parent, result);
                    current = parent;
                    if (current === commonPrefix) {
                        break;
                    }
                }
            }
            function getCommonPrefix(directory, resolution) {
                if (resolution === undefined) {
                    return undefined;
                }
                var resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName);
                // find first position where directory and resolution differs
                var i = 0;
                while (i < Math.min(directory.length, resolutionDirectory.length) && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
                    i++;
                }
                // find last directory separator before position i
                var sep = directory.lastIndexOf(ts.directorySeparator, i);
                if (sep < 0) {
                    return undefined;
                }
                return directory.substr(0, sep);
            }
        }
    }
    ts.createModuleResolutionCache = createModuleResolutionCache;
    function resolveModuleName(moduleName, containingFile, compilerOptions, host, cache) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
        }
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
        var result = perFolderCache && perFolderCache.get(moduleName);
        if (result) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
            }
        }
        else {
            var moduleResolution = compilerOptions.moduleResolution;
            if (moduleResolution === undefined) {
                moduleResolution = ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            switch (moduleResolution) {
                case ts.ModuleResolutionKind.NodeJs:
                    result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache);
                    break;
                case ts.ModuleResolutionKind.Classic:
                    result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
                    break;
                default:
                    ts.Debug.fail("Unexpected moduleResolution: " + moduleResolution);
            }
            if (perFolderCache) {
                perFolderCache.set(moduleName, result);
                // put result in per-module name cache
                var perModuleNameCache = cache.getOrCreateCacheForModuleName(moduleName);
                if (perModuleNameCache) {
                    perModuleNameCache.set(containingDirectory, result);
                }
            }
        }
        if (traceEnabled) {
            if (result.resolvedModule) {
                trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
            }
            else {
                trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName);
            }
        }
        return result;
    }
    ts.resolveModuleName = resolveModuleName;
    /**
     * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
     * mitigate differences between design time structure of the project and its runtime counterpart so the same import name
     * can be resolved successfully by TypeScript compiler and runtime module loader.
     * If these settings are set then loading procedure will try to use them to resolve module name and it can of failure it will
     * fallback to standard resolution routine.
     *
     * - baseUrl - this setting controls how non-relative module names are resolved. If this setting is specified then non-relative
     * names will be resolved relative to baseUrl: i.e. if baseUrl is '/a/b' then candidate location to resolve module name 'c/d' will
     * be '/a/b/c/d'
     * - paths - this setting can only be used when baseUrl is specified. allows to tune how non-relative module names
     * will be resolved based on the content of the module name.
     * Structure of 'paths' compiler options
     * 'paths': {
     *    pattern-1: [...substitutions],
     *    pattern-2: [...substitutions],
     *    ...
     *    pattern-n: [...substitutions]
     * }
     * Pattern here is a string that can contain zero or one '*' character. During module resolution module name will be matched against
     * all patterns in the list. Matching for patterns that don't contain '*' means that module name must be equal to pattern respecting the case.
     * If pattern contains '*' then to match pattern "<prefix>*<suffix>" module name must start with the <prefix> and end with <suffix>.
     * <MatchedStar> denotes part of the module name between <prefix> and <suffix>.
     * If module name can be matches with multiple patterns then pattern with the longest prefix will be picked.
     * After selecting pattern we'll use list of substitutions to get candidate locations of the module and the try to load module
     * from the candidate location.
     * Substitution is a string that can contain zero or one '*'. To get candidate location from substitution we'll pick every
     * substitution in the list and replace '*' with <MatchedStar> string. If candidate location is not rooted it
     * will be converted to absolute using baseUrl.
     * For example:
     * baseUrl: /a/b/c
     * "paths": {
     *     // match all module names
     *     "*": [
     *         "*",        // use matched name as is,
     *                     // <matched name> will be looked as /a/b/c/<matched name>
     *
     *         "folder1/*" // substitution will convert matched name to 'folder1/<matched name>',
     *                     // since it is not rooted then final candidate location will be /a/b/c/folder1/<matched name>
     *     ],
     *     // match module names that start with 'components/'
     *     "components/*": [ "/root/components/*" ] // substitution will convert /components/folder1/<matched name> to '/root/components/folder1/<matched name>',
     *                                              // it is rooted so it will be final candidate location
     * }
     *
     * 'rootDirs' allows the project to be spreaded across multiple locations and resolve modules with relative names as if
     * they were in the same location. For example lets say there are two files
     * '/local/src/content/file1.ts'
     * '/shared/components/contracts/src/content/protocols/file2.ts'
     * After bundling content of '/shared/components/contracts/src' will be merged with '/local/src' so
     * if file1 has the following import 'import {x} from "./protocols/file2"' it will be resolved successfully in runtime.
     * 'rootDirs' provides the way to tell compiler that in order to get the whole project it should behave as if content of all
     * root dirs were merged together.
     * I.e. for the example above 'rootDirs' will have two entries: [ '/local/src', '/shared/components/contracts/src' ].
     * Compiler will first convert './protocols/file2' into absolute path relative to the location of containing file:
     * '/local/src/content/protocols/file2' and try to load it - failure.
     * Then it will search 'rootDirs' looking for a longest matching prefix of this absolute path and if such prefix is found - absolute path will
     * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
     * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
     */
    function tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state) {
        if (!ts.isExternalModuleNameRelative(moduleName)) {
            return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
        }
        else {
            return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
        }
    }
    function tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state) {
        if (!state.compilerOptions.rootDirs) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
        var matchedRootDir;
        var matchedNormalizedPrefix;
        for (var _i = 0, _a = state.compilerOptions.rootDirs; _i < _a.length; _i++) {
            var rootDir = _a[_i];
            // rootDirs are expected to be absolute
            // in case of tsconfig.json this will happen automatically - compiler will expand relative names
            // using location of tsconfig.json as base location
            var normalizedRoot = ts.normalizePath(rootDir);
            if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) {
                normalizedRoot += ts.directorySeparator;
            }
            var isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) &&
                (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix);
            }
            if (isLongestMatchingPrefix) {
                matchedNormalizedPrefix = normalizedRoot;
                matchedRootDir = rootDir;
            }
        }
        if (matchedNormalizedPrefix) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix);
            }
            var suffix = candidate.substr(matchedNormalizedPrefix.length);
            // first - try to load from a initial location
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
            }
            var resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
            if (resolvedFileName) {
                return resolvedFileName;
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs);
            }
            // then try to resolve using remaining entries in rootDirs
            for (var _b = 0, _c = state.compilerOptions.rootDirs; _b < _c.length; _b++) {
                var rootDir = _c[_b];
                if (rootDir === matchedRootDir) {
                    // skip the initially matched entry
                    continue;
                }
                var candidate_1 = ts.combinePaths(ts.normalizePath(rootDir), suffix);
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate_1);
                }
                var baseDirectory = ts.getDirectoryPath(candidate_1);
                var resolvedFileName_1 = loader(extensions, candidate_1, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
                if (resolvedFileName_1) {
                    return resolvedFileName_1;
                }
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed);
            }
        }
        return undefined;
    }
    function tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state) {
        if (!state.compilerOptions.baseUrl) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, state.compilerOptions.baseUrl, moduleName);
        }
        // string is for exact match
        var matchedPattern = undefined;
        if (state.compilerOptions.paths) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
            }
            matchedPattern = ts.matchPatternOrExact(ts.getOwnKeys(state.compilerOptions.paths), moduleName);
        }
        if (matchedPattern) {
            var matchedStar_1 = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName);
            var matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
            }
            return ts.forEach(state.compilerOptions.paths[matchedPatternText], function (subst) {
                var path = matchedStar_1 ? subst.replace("*", matchedStar_1) : subst;
                var candidate = ts.normalizePath(ts.combinePaths(state.compilerOptions.baseUrl, path));
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
                }
                // A path mapping may have an extension, in contrast to an import, which should omit it.
                var extension = ts.tryGetExtensionFromPath(candidate);
                if (extension !== undefined) {
                    var path_1 = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
                    if (path_1 !== undefined) {
                        return noPackageId({ path: path_1, ext: extension });
                    }
                }
                return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
            });
        }
        else {
            var candidate = ts.normalizePath(ts.combinePaths(state.compilerOptions.baseUrl, moduleName));
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate);
            }
            return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
        }
    }
    function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) {
        return nodeModuleNameResolverWorker(moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
    }
    ts.nodeModuleNameResolver = nodeModuleNameResolver;
    /**
     * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
     * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
     * Throws an error if the module can't be resolved.
     */
    /* @internal */
    function resolveJavaScriptModule(moduleName, initialDir, host) {
        var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations;
        if (!resolvedModule) {
            throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", "));
        }
        return resolvedModule.resolvedFileName;
    }
    ts.resolveJavaScriptModule = resolveJavaScriptModule;
    function nodeModuleNameResolverWorker(moduleName, containingDirectory, compilerOptions, host, cache, jsOnly) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled };
        var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript));
        if (result && result.value) {
            var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport;
            return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
        }
        return { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
        function tryResolve(extensions) {
            var loader = function (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { return nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true); };
            var resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
            if (resolved) {
                return toSearchResult({ resolved: resolved, isExternalLibraryImport: false });
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
                }
                var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache);
                if (!resolved_1)
                    return undefined;
                var resolvedValue = resolved_1.value;
                if (!compilerOptions.preserveSymlinks) {
                    resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realPath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension });
                }
                // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
                return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
            }
            else {
                var _a = ts.normalizePathAndParts(ts.combinePaths(containingDirectory, moduleName)), candidate = _a.path, parts = _a.parts;
                var resolved_2 = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
                // Treat explicit "node_modules" import as an external library import.
                return resolved_2 && toSearchResult({ resolved: resolved_2, isExternalLibraryImport: ts.contains(parts, "node_modules") });
            }
        }
    }
    function realPath(path, host, traceEnabled) {
        if (!host.realpath) {
            return path;
        }
        var real = ts.normalizePath(host.realpath(path));
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real);
        }
        return real;
    }
    function nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) {
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
        }
        if (!ts.pathEndsWithDirectorySeparator(candidate)) {
            if (!onlyRecordFailures) {
                var parentOfCandidate = ts.getDirectoryPath(candidate);
                if (!directoryProbablyExists(parentOfCandidate, state.host)) {
                    if (state.traceEnabled) {
                        trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate);
                    }
                    onlyRecordFailures = true;
                }
            }
            var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
            if (resolvedFromFile) {
                return noPackageId(resolvedFromFile);
            }
        }
        if (!onlyRecordFailures) {
            var candidateExists = directoryProbablyExists(candidate, state.host);
            if (!candidateExists) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate);
                }
                onlyRecordFailures = true;
            }
        }
        return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson);
    }
    /* @internal */
    function directoryProbablyExists(directoryName, host) {
        // if host does not support 'directoryExists' assume that directory will exist
        return !host.directoryExists || host.directoryExists(directoryName);
    }
    ts.directoryProbablyExists = directoryProbablyExists;
    function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) {
        return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state));
    }
    /**
     * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
     * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
     */
    function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) {
        // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
        var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
        if (resolvedByAddingExtension) {
            return resolvedByAddingExtension;
        }
        // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
        // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
        if (ts.hasJavaScriptFileExtension(candidate)) {
            var extensionless = ts.removeFileExtension(candidate);
            if (state.traceEnabled) {
                var extension = candidate.substring(extensionless.length);
                trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
            }
            return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state);
        }
    }
    /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
    function tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
            var directory = ts.getDirectoryPath(candidate);
            if (directory) {
                onlyRecordFailures = !directoryProbablyExists(directory, state.host);
            }
        }
        switch (extensions) {
            case Extensions.DtsOnly:
                return tryExtension(".d.ts" /* Dts */);
            case Extensions.TypeScript:
                return tryExtension(".ts" /* Ts */) || tryExtension(".tsx" /* Tsx */) || tryExtension(".d.ts" /* Dts */);
            case Extensions.JavaScript:
                return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */);
        }
        function tryExtension(ext) {
            var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
            return path && { path: path, ext: ext };
        }
    }
    /** Return the file if it exists. */
    function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            if (state.host.fileExists(fileName)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName);
                }
                return fileName;
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName);
                }
            }
        }
        failedLookupLocations.push(fileName);
        return undefined;
    }
    function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) {
        if (considerPackageJson === void 0) { considerPackageJson = true; }
        var _a = considerPackageJson
            ? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state)
            : { packageJsonContent: undefined, packageId: undefined }, packageJsonContent = _a.packageJsonContent, packageId = _a.packageId;
        return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent));
    }
    function loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent) {
        var fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state);
        if (fromPackageJson) {
            return fromPackageJson;
        }
        var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
        return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
    }
    function getPackageJsonInfo(nodeModuleDirectory, subModuleName, failedLookupLocations, onlyRecordFailures, _a) {
        var host = _a.host, traceEnabled = _a.traceEnabled;
        var directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host);
        var packageJsonPath = pathToPackageJson(nodeModuleDirectory);
        if (directoryExists && host.fileExists(packageJsonPath)) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath);
            }
            var packageJsonContent = readJson(packageJsonPath, host);
            var packageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
                ? { name: packageJsonContent.name, subModuleName: subModuleName, version: packageJsonContent.version }
                : undefined;
            return { found: true, packageJsonContent: packageJsonContent, packageId: packageId };
        }
        else {
            if (directoryExists && traceEnabled) {
                trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath);
            }
            // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
            failedLookupLocations.push(packageJsonPath);
            return { found: false, packageJsonContent: undefined, packageId: undefined };
        }
    }
    function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) {
        var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state);
        if (!file) {
            return undefined;
        }
        var onlyRecordFailures = !directoryProbablyExists(ts.getDirectoryPath(file), state.host);
        var fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state);
        if (fromFile) {
            var resolved = fromFile && resolvedIfExtensionMatches(extensions, fromFile);
            if (resolved) {
                return resolved;
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
            }
        }
        // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
        var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
        // Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
        var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false);
        if (result) {
            // It won't have a `packageId` set, because we disabled `considerPackageJson`.
            ts.Debug.assert(result.packageId === undefined);
            return { path: result.path, ext: result.extension };
        }
    }
    /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
    function resolvedIfExtensionMatches(extensions, path) {
        var ext = ts.tryGetExtensionFromPath(path);
        return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined;
    }
    /** True if `extension` is one of the supported `extensions`. */
    function extensionIsOk(extensions, extension) {
        switch (extensions) {
            case Extensions.JavaScript:
                return extension === ".js" /* Js */ || extension === ".jsx" /* Jsx */;
            case Extensions.TypeScript:
                return extension === ".ts" /* Ts */ || extension === ".tsx" /* Tsx */ || extension === ".d.ts" /* Dts */;
            case Extensions.DtsOnly:
                return extension === ".d.ts" /* Dts */;
        }
    }
    function pathToPackageJson(directory) {
        return ts.combinePaths(directory, "package.json");
    }
    function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) {
        var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
        // First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
        var packageJsonContent;
        var packageId;
        var packageInfo = getPackageJsonInfo(candidate, "", failedLookupLocations, /*onlyRecordFailures*/ !nodeModulesFolderExists, state);
        if (packageInfo.found) {
            (packageJsonContent = packageInfo.packageJsonContent, packageId = packageInfo.packageId);
        }
        else {
            var _a = getPackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
            if (rest !== "") {
                var packageRootPath = ts.combinePaths(nodeModulesFolder, packageName);
                // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId.
                packageId = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state).packageId;
            }
        }
        var pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
            loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
        return withPackageId(packageId, pathAndExtension);
    }
    /* @internal */
    function getPackageName(moduleName) {
        var idx = moduleName.indexOf(ts.directorySeparator);
        if (moduleName[0] === "@") {
            idx = moduleName.indexOf(ts.directorySeparator, idx + 1);
        }
        return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
    }
    ts.getPackageName = getPackageName;
    function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) {
        return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache);
    }
    function loadModuleFromNodeModulesAtTypes(moduleName, directory, failedLookupLocations, state) {
        // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
        return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined);
    }
    function loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, typesOnly, cache) {
        var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
        return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), function (ancestorDirectory) {
            if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") {
                var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host);
                if (resolutionFromCache) {
                    return resolutionFromCache;
                }
                return toSearchResult(loadModuleFromNodeModulesOneLevel(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly));
            }
        });
    }
    /** Load a module from a single node_modules directory, but not from any ancestors' node_modules directories. */
    function loadModuleFromNodeModulesOneLevel(extensions, moduleName, directory, failedLookupLocations, state, typesOnly) {
        if (typesOnly === void 0) { typesOnly = false; }
        var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
        var nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
        if (!nodeModulesFolderExists && state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder);
        }
        var packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state);
        if (packageResult) {
            return packageResult;
        }
        if (extensions !== Extensions.JavaScript) {
            var nodeModulesAtTypes_1 = ts.combinePaths(nodeModulesFolder, "@types");
            var nodeModulesAtTypesExists = nodeModulesFolderExists;
            if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes_1, state.host)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes_1);
                }
                nodeModulesAtTypesExists = false;
            }
            return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackage(moduleName, state), nodeModulesAtTypes_1, nodeModulesAtTypesExists, failedLookupLocations, state);
        }
    }
    /** Double underscores are used in DefinitelyTyped to delimit scoped packages. */
    var mangledScopedPackageSeparator = "__";
    /** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
    function mangleScopedPackage(packageName, state) {
        var mangled = getMangledNameForScopedPackage(packageName);
        if (state.traceEnabled && mangled !== packageName) {
            trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled);
        }
        return mangled;
    }
    /* @internal */
    function getTypesPackageName(packageName) {
        return "@types/" + getMangledNameForScopedPackage(packageName);
    }
    ts.getTypesPackageName = getTypesPackageName;
    function getMangledNameForScopedPackage(packageName) {
        if (ts.startsWith(packageName, "@")) {
            var replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
            if (replaceSlash !== packageName) {
                return replaceSlash.slice(1); // Take off the "@"
            }
        }
        return packageName;
    }
    /* @internal */
    function getPackageNameFromAtTypesDirectory(mangledName) {
        var withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/");
        if (withoutAtTypePrefix !== mangledName) {
            return ts.stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ?
                "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
                withoutAtTypePrefix;
        }
        return mangledName;
    }
    ts.getPackageNameFromAtTypesDirectory = getPackageNameFromAtTypesDirectory;
    function tryFindNonRelativeModuleNameInCache(cache, moduleName, containingDirectory, traceEnabled, host) {
        var result = cache && cache.get(containingDirectory);
        if (result) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
            }
            return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
        }
    }
    function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled };
        var failedLookupLocations = [];
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
        return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
        function tryResolve(extensions) {
            var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state);
            if (resolvedUsingSettings) {
                return { value: resolvedUsingSettings };
            }
            var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                // Climb up parent directories looking for a module.
                var resolved_3 = ts.forEachAncestorDirectory(containingDirectory, function (directory) {
                    var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host);
                    if (resolutionFromCache) {
                        return resolutionFromCache;
                    }
                    var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName));
                    return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state));
                });
                if (resolved_3) {
                    return resolved_3;
                }
                if (extensions === Extensions.TypeScript) {
                    // If we didn't find the file normally, look it up in @types.
                    return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
                }
            }
            else {
                var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
                return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state));
            }
        }
    }
    ts.classicNameResolver = classicNameResolver;
    /**
     * LSHost may load a module from a global cache of typings.
     * This is the minumum code needed to expose that functionality; the rest is in LSHost.
     */
    /* @internal */
    function loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
        }
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled };
        var failedLookupLocations = [];
        var resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state);
        return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
    }
    ts.loadModuleFromGlobalCache = loadModuleFromGlobalCache;
    /**
     * Wraps value to SearchResult.
     * @returns undefined if value is undefined or { value } otherwise
     */
    function toSearchResult(value) {
        return value !== undefined ? { value: value } : undefined;
    }
})(ts || (ts = {}));
/// <reference path="moduleNameResolver.ts"/>
/// <reference path="binder.ts"/>
/// <reference path="symbolWalker.ts" />
/* @internal */
var ts;
(function (ts) {
    var ambientModuleSymbolRegex = /^".+"$/;
    var nextSymbolId = 1;
    var nextNodeId = 1;
    var nextMergeId = 1;
    var nextFlowId = 1;
    function getNodeId(node) {
        if (!node.id) {
            node.id = nextNodeId;
            nextNodeId++;
        }
        return node.id;
    }
    ts.getNodeId = getNodeId;
    function getSymbolId(symbol) {
        if (!symbol.id) {
            symbol.id = nextSymbolId;
            nextSymbolId++;
        }
        return symbol.id;
    }
    ts.getSymbolId = getSymbolId;
    function isInstantiatedModule(node, preserveConstEnums) {
        var moduleState = ts.getModuleInstanceState(node);
        return moduleState === 1 /* Instantiated */ ||
            (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */);
    }
    ts.isInstantiatedModule = isInstantiatedModule;
    function createTypeChecker(host, produceDiagnostics) {
        // Cancellation that controls whether or not we can cancel in the middle of type checking.
        // In general cancelling is *not* safe for the type checker.  We might be in the middle of
        // computing something, and we will leave our internals in an inconsistent state.  Callers
        // who set the cancellation token should catch if a cancellation exception occurs, and
        // should throw away and create a new TypeChecker.
        //
        // Currently we only support setting the cancellation token when getting diagnostics.  This
        // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
        // they no longer need the information (for example, if the user started editing again).
        var cancellationToken;
        var requestedExternalEmitHelpers;
        var externalHelpersModule;
        var Symbol = ts.objectAllocator.getSymbolConstructor();
        var Type = ts.objectAllocator.getTypeConstructor();
        var Signature = ts.objectAllocator.getSignatureConstructor();
        var typeCount = 0;
        var symbolCount = 0;
        var enumCount = 0;
        var symbolInstantiationDepth = 0;
        var emptySymbols = ts.createSymbolTable();
        var identityMapper = ts.identity;
        var compilerOptions = host.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var modulekind = ts.getEmitModuleKind(compilerOptions);
        var noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters;
        var allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ts.ModuleKind.System;
        var strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks;
        var strictFunctionTypes = compilerOptions.strictFunctionTypes === undefined ? compilerOptions.strict : compilerOptions.strictFunctionTypes;
        var noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny;
        var noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis;
        var emitResolver = createResolver();
        var nodeBuilder = createNodeBuilder();
        var undefinedSymbol = createSymbol(4 /* Property */, "undefined");
        undefinedSymbol.declarations = [];
        var argumentsSymbol = createSymbol(4 /* Property */, "arguments");
        /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
        var apparentArgumentCount;
        // for public members that accept a Node or one of its subtypes, we must guard against
        // synthetic nodes created during transformations by calling `getParseTreeNode`.
        // for most of these, we perform the guard only on `checker` to avoid any possible
        // extra cost of calling `getParseTreeNode` when calling these functions from inside the
        // checker.
        var checker = {
            getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); },
            getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); },
            getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; },
            getTypeCount: function () { return typeCount; },
            isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; },
            isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; },
            isUnknownSymbol: function (symbol) { return symbol === unknownSymbol; },
            getMergedSymbol: getMergedSymbol,
            getDiagnostics: getDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getTypeOfSymbolAtLocation: function (symbol, location) {
                location = ts.getParseTreeNode(location);
                return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType;
            },
            getSymbolsOfParameterPropertyDeclaration: function (parameter, parameterName) {
                parameter = ts.getParseTreeNode(parameter, ts.isParameter);
                ts.Debug.assert(parameter !== undefined, "Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
                return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName));
            },
            getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
            getPropertiesOfType: getPropertiesOfType,
            getPropertyOfType: function (type, name) { return getPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getIndexInfoOfType: getIndexInfoOfType,
            getSignaturesOfType: getSignaturesOfType,
            getIndexTypeOfType: getIndexTypeOfType,
            getBaseTypes: getBaseTypes,
            getBaseTypeOfLiteralType: getBaseTypeOfLiteralType,
            getWidenedType: getWidenedType,
            getTypeFromTypeNode: function (node) {
                node = ts.getParseTreeNode(node, ts.isTypeNode);
                return node ? getTypeFromTypeNode(node) : unknownType;
            },
            getParameterType: getTypeAtPosition,
            getReturnTypeOfSignature: getReturnTypeOfSignature,
            getNullableType: getNullableType,
            getNonNullableType: getNonNullableType,
            typeToTypeNode: nodeBuilder.typeToTypeNode,
            indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
            signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration,
            getSymbolsInScope: function (location, meaning) {
                location = ts.getParseTreeNode(location);
                return location ? getSymbolsInScope(location, meaning) : [];
            },
            getSymbolAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getSymbolAtLocation(node) : undefined;
            },
            getShorthandAssignmentValueSymbol: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getShorthandAssignmentValueSymbol(node) : undefined;
            },
            getExportSpecifierLocalTargetSymbol: function (node) {
                node = ts.getParseTreeNode(node, ts.isExportSpecifier);
                return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
            },
            getExportSymbolOfSymbol: function (symbol) {
                return getMergedSymbol(symbol.exportSymbol || symbol);
            },
            getTypeAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getTypeOfNode(node) : unknownType;
            },
            getPropertySymbolOfDestructuringAssignment: function (location) {
                location = ts.getParseTreeNode(location, ts.isIdentifier);
                return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
            },
            signatureToString: function (signature, enclosingDeclaration, flags, kind) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind);
            },
            typeToString: function (type, enclosingDeclaration, flags) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            getSymbolDisplayBuilder: getSymbolDisplayBuilder,
            symbolToString: function (symbol, enclosingDeclaration, meaning) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning);
            },
            getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
            getRootSymbols: getRootSymbols,
            getContextualType: function (node) {
                node = ts.getParseTreeNode(node, ts.isExpression);
                return node ? getContextualType(node) : undefined;
            },
            getFullyQualifiedName: getFullyQualifiedName,
            getResolvedSignature: function (node, candidatesOutArray, theArgumentCount) {
                node = ts.getParseTreeNode(node, ts.isCallLikeExpression);
                apparentArgumentCount = theArgumentCount;
                var res = node ? getResolvedSignature(node, candidatesOutArray) : undefined;
                apparentArgumentCount = undefined;
                return res;
            },
            getConstantValue: function (node) {
                node = ts.getParseTreeNode(node, canHaveConstantValue);
                return node ? getConstantValue(node) : undefined;
            },
            isValidPropertyAccess: function (node, propertyName) {
                node = ts.getParseTreeNode(node, ts.isPropertyAccessOrQualifiedName);
                return node ? isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName)) : false;
            },
            getSignatureFromDeclaration: function (declaration) {
                declaration = ts.getParseTreeNode(declaration, ts.isFunctionLike);
                return declaration ? getSignatureFromDeclaration(declaration) : undefined;
            },
            isImplementationOfOverload: function (node) {
                var parsed = ts.getParseTreeNode(node, ts.isFunctionLike);
                return parsed ? isImplementationOfOverload(parsed) : undefined;
            },
            getImmediateAliasedSymbol: function (symbol) {
                ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
                var links = getSymbolLinks(symbol);
                if (!links.immediateTarget) {
                    var node = getDeclarationOfAliasSymbol(symbol);
                    ts.Debug.assert(!!node);
                    links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true);
                }
                return links.immediateTarget;
            },
            getAliasedSymbol: resolveAlias,
            getEmitResolver: getEmitResolver,
            getExportsOfModule: getExportsOfModuleAsArray,
            getExportsAndPropertiesOfModule: getExportsAndPropertiesOfModule,
            getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier),
            getAmbientModules: getAmbientModules,
            getAllAttributesTypeFromJsxOpeningLikeElement: function (node) {
                node = ts.getParseTreeNode(node, ts.isJsxOpeningLikeElement);
                return node ? getAllAttributesTypeFromJsxOpeningLikeElement(node) : undefined;
            },
            getJsxIntrinsicTagNames: getJsxIntrinsicTagNames,
            isOptionalParameter: function (node) {
                node = ts.getParseTreeNode(node, ts.isParameter);
                return node ? isOptionalParameter(node) : false;
            },
            tryGetMemberInModuleExports: function (name, symbol) { return tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol); },
            tryGetMemberInModuleExportsAndProperties: function (name, symbol) { return tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol); },
            tryFindAmbientModuleWithoutAugmentations: function (moduleName) {
                // we deliberately exclude augmentations
                // since we are only interested in declarations of the module itself
                return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
            },
            getApparentType: getApparentType,
            getUnionType: getUnionType,
            createAnonymousType: createAnonymousType,
            createSignature: createSignature,
            createSymbol: createSymbol,
            createIndexInfo: createIndexInfo,
            getAnyType: function () { return anyType; },
            getStringType: function () { return stringType; },
            getNumberType: function () { return numberType; },
            createPromiseType: createPromiseType,
            createArrayType: createArrayType,
            getBooleanType: function () { return booleanType; },
            getVoidType: function () { return voidType; },
            getUndefinedType: function () { return undefinedType; },
            getNullType: function () { return nullType; },
            getESSymbolType: function () { return esSymbolType; },
            getNeverType: function () { return neverType; },
            isSymbolAccessible: isSymbolAccessible,
            isArrayLikeType: isArrayLikeType,
            getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes,
            getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); },
            getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
            getBaseConstraintOfType: getBaseConstraintOfType,
            resolveName: function (name, location, meaning) {
                return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
            },
            getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); },
        };
        var tupleTypes = [];
        var unionTypes = ts.createMap();
        var intersectionTypes = ts.createMap();
        var literalTypes = ts.createMap();
        var indexedAccessTypes = ts.createMap();
        var evolvingArrayTypes = [];
        var unknownSymbol = createSymbol(4 /* Property */, "unknown");
        var resolvingSymbol = createSymbol(0, "__resolving__" /* Resolving */);
        var anyType = createIntrinsicType(1 /* Any */, "any");
        var autoType = createIntrinsicType(1 /* Any */, "any");
        var unknownType = createIntrinsicType(1 /* Any */, "unknown");
        var undefinedType = createIntrinsicType(2048 /* Undefined */, "undefined");
        var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(2048 /* Undefined */ | 2097152 /* ContainsWideningType */, "undefined");
        var nullType = createIntrinsicType(4096 /* Null */, "null");
        var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(4096 /* Null */ | 2097152 /* ContainsWideningType */, "null");
        var stringType = createIntrinsicType(2 /* String */, "string");
        var numberType = createIntrinsicType(4 /* Number */, "number");
        var trueType = createIntrinsicType(128 /* BooleanLiteral */, "true");
        var falseType = createIntrinsicType(128 /* BooleanLiteral */, "false");
        var booleanType = createBooleanType([trueType, falseType]);
        var esSymbolType = createIntrinsicType(512 /* ESSymbol */, "symbol");
        var voidType = createIntrinsicType(1024 /* Void */, "void");
        var neverType = createIntrinsicType(8192 /* Never */, "never");
        var silentNeverType = createIntrinsicType(8192 /* Never */, "never");
        var nonPrimitiveType = createIntrinsicType(16777216 /* NonPrimitive */, "object");
        var emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyTypeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
        emptyTypeLiteralSymbol.members = ts.createSymbolTable();
        var emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyGenericType.instantiations = ts.createMap();
        var anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
        // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
        anyFunctionType.flags |= 8388608 /* ContainsAnyFunctionType */;
        var noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var markerSuperType = createType(16384 /* TypeParameter */);
        var markerSubType = createType(16384 /* TypeParameter */);
        markerSubType.constraint = markerSuperType;
        var markerOtherType = createType(16384 /* TypeParameter */);
        var anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
        var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
        var jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
        var globals = ts.createSymbolTable();
        var ambientModulesCache;
        /**
         * List of every ambient module with a "*" wildcard.
         * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
         * This is only used if there is no exact match.
         */
        var patternAmbientModules;
        var globalObjectType;
        var globalFunctionType;
        var globalArrayType;
        var globalReadonlyArrayType;
        var globalStringType;
        var globalNumberType;
        var globalBooleanType;
        var globalRegExpType;
        var globalThisType;
        var anyArrayType;
        var autoArrayType;
        var anyReadonlyArrayType;
        // The library files are only loaded when the feature is used.
        // This allows users to just specify library files they want to used through --lib
        // and they will not get an error from not having unrelated library files
        var deferredGlobalESSymbolConstructorSymbol;
        var deferredGlobalESSymbolType;
        var deferredGlobalTypedPropertyDescriptorType;
        var deferredGlobalPromiseType;
        var deferredGlobalPromiseConstructorSymbol;
        var deferredGlobalPromiseConstructorLikeType;
        var deferredGlobalIterableType;
        var deferredGlobalIteratorType;
        var deferredGlobalIterableIteratorType;
        var deferredGlobalAsyncIterableType;
        var deferredGlobalAsyncIteratorType;
        var deferredGlobalAsyncIterableIteratorType;
        var deferredGlobalTemplateStringsArrayType;
        var deferredJsxElementClassType;
        var deferredJsxElementType;
        var deferredJsxStatelessElementType;
        var deferredNodes;
        var deferredUnusedIdentifierNodes;
        var flowLoopStart = 0;
        var flowLoopCount = 0;
        var sharedFlowCount = 0;
        var flowAnalysisDisabled = false;
        var emptyStringType = getLiteralType("");
        var zeroType = getLiteralType(0);
        var resolutionTargets = [];
        var resolutionResults = [];
        var resolutionPropertyNames = [];
        var suggestionCount = 0;
        var maximumSuggestionCount = 10;
        var mergedSymbols = [];
        var symbolLinks = [];
        var nodeLinks = [];
        var flowLoopCaches = [];
        var flowLoopNodes = [];
        var flowLoopKeys = [];
        var flowLoopTypes = [];
        var sharedFlowNodes = [];
        var sharedFlowTypes = [];
        var potentialThisCollisions = [];
        var potentialNewTargetCollisions = [];
        var awaitedTypeStack = [];
        var diagnostics = ts.createDiagnosticCollection();
        var TypeFacts;
        (function (TypeFacts) {
            TypeFacts[TypeFacts["None"] = 0] = "None";
            TypeFacts[TypeFacts["TypeofEQString"] = 1] = "TypeofEQString";
            TypeFacts[TypeFacts["TypeofEQNumber"] = 2] = "TypeofEQNumber";
            TypeFacts[TypeFacts["TypeofEQBoolean"] = 4] = "TypeofEQBoolean";
            TypeFacts[TypeFacts["TypeofEQSymbol"] = 8] = "TypeofEQSymbol";
            TypeFacts[TypeFacts["TypeofEQObject"] = 16] = "TypeofEQObject";
            TypeFacts[TypeFacts["TypeofEQFunction"] = 32] = "TypeofEQFunction";
            TypeFacts[TypeFacts["TypeofEQHostObject"] = 64] = "TypeofEQHostObject";
            TypeFacts[TypeFacts["TypeofNEString"] = 128] = "TypeofNEString";
            TypeFacts[TypeFacts["TypeofNENumber"] = 256] = "TypeofNENumber";
            TypeFacts[TypeFacts["TypeofNEBoolean"] = 512] = "TypeofNEBoolean";
            TypeFacts[TypeFacts["TypeofNESymbol"] = 1024] = "TypeofNESymbol";
            TypeFacts[TypeFacts["TypeofNEObject"] = 2048] = "TypeofNEObject";
            TypeFacts[TypeFacts["TypeofNEFunction"] = 4096] = "TypeofNEFunction";
            TypeFacts[TypeFacts["TypeofNEHostObject"] = 8192] = "TypeofNEHostObject";
            TypeFacts[TypeFacts["EQUndefined"] = 16384] = "EQUndefined";
            TypeFacts[TypeFacts["EQNull"] = 32768] = "EQNull";
            TypeFacts[TypeFacts["EQUndefinedOrNull"] = 65536] = "EQUndefinedOrNull";
            TypeFacts[TypeFacts["NEUndefined"] = 131072] = "NEUndefined";
            TypeFacts[TypeFacts["NENull"] = 262144] = "NENull";
            TypeFacts[TypeFacts["NEUndefinedOrNull"] = 524288] = "NEUndefinedOrNull";
            TypeFacts[TypeFacts["Truthy"] = 1048576] = "Truthy";
            TypeFacts[TypeFacts["Falsy"] = 2097152] = "Falsy";
            TypeFacts[TypeFacts["Discriminatable"] = 4194304] = "Discriminatable";
            TypeFacts[TypeFacts["All"] = 8388607] = "All";
            // The following members encode facts about particular kinds of types for use in the getTypeFacts function.
            // The presence of a particular fact means that the given test is true for some (and possibly all) values
            // of that kind of type.
            TypeFacts[TypeFacts["BaseStringStrictFacts"] = 933633] = "BaseStringStrictFacts";
            TypeFacts[TypeFacts["BaseStringFacts"] = 3145473] = "BaseStringFacts";
            TypeFacts[TypeFacts["StringStrictFacts"] = 4079361] = "StringStrictFacts";
            TypeFacts[TypeFacts["StringFacts"] = 4194049] = "StringFacts";
            TypeFacts[TypeFacts["EmptyStringStrictFacts"] = 3030785] = "EmptyStringStrictFacts";
            TypeFacts[TypeFacts["EmptyStringFacts"] = 3145473] = "EmptyStringFacts";
            TypeFacts[TypeFacts["NonEmptyStringStrictFacts"] = 1982209] = "NonEmptyStringStrictFacts";
            TypeFacts[TypeFacts["NonEmptyStringFacts"] = 4194049] = "NonEmptyStringFacts";
            TypeFacts[TypeFacts["BaseNumberStrictFacts"] = 933506] = "BaseNumberStrictFacts";
            TypeFacts[TypeFacts["BaseNumberFacts"] = 3145346] = "BaseNumberFacts";
            TypeFacts[TypeFacts["NumberStrictFacts"] = 4079234] = "NumberStrictFacts";
            TypeFacts[TypeFacts["NumberFacts"] = 4193922] = "NumberFacts";
            TypeFacts[TypeFacts["ZeroStrictFacts"] = 3030658] = "ZeroStrictFacts";
            TypeFacts[TypeFacts["ZeroFacts"] = 3145346] = "ZeroFacts";
            TypeFacts[TypeFacts["NonZeroStrictFacts"] = 1982082] = "NonZeroStrictFacts";
            TypeFacts[TypeFacts["NonZeroFacts"] = 4193922] = "NonZeroFacts";
            TypeFacts[TypeFacts["BaseBooleanStrictFacts"] = 933252] = "BaseBooleanStrictFacts";
            TypeFacts[TypeFacts["BaseBooleanFacts"] = 3145092] = "BaseBooleanFacts";
            TypeFacts[TypeFacts["BooleanStrictFacts"] = 4078980] = "BooleanStrictFacts";
            TypeFacts[TypeFacts["BooleanFacts"] = 4193668] = "BooleanFacts";
            TypeFacts[TypeFacts["FalseStrictFacts"] = 3030404] = "FalseStrictFacts";
            TypeFacts[TypeFacts["FalseFacts"] = 3145092] = "FalseFacts";
            TypeFacts[TypeFacts["TrueStrictFacts"] = 1981828] = "TrueStrictFacts";
            TypeFacts[TypeFacts["TrueFacts"] = 4193668] = "TrueFacts";
            TypeFacts[TypeFacts["SymbolStrictFacts"] = 1981320] = "SymbolStrictFacts";
            TypeFacts[TypeFacts["SymbolFacts"] = 4193160] = "SymbolFacts";
            TypeFacts[TypeFacts["ObjectStrictFacts"] = 6166480] = "ObjectStrictFacts";
            TypeFacts[TypeFacts["ObjectFacts"] = 8378320] = "ObjectFacts";
            TypeFacts[TypeFacts["FunctionStrictFacts"] = 6164448] = "FunctionStrictFacts";
            TypeFacts[TypeFacts["FunctionFacts"] = 8376288] = "FunctionFacts";
            TypeFacts[TypeFacts["UndefinedFacts"] = 2457472] = "UndefinedFacts";
            TypeFacts[TypeFacts["NullFacts"] = 2340752] = "NullFacts";
        })(TypeFacts || (TypeFacts = {}));
        var typeofEQFacts = ts.createMapFromTemplate({
            "string": 1 /* TypeofEQString */,
            "number": 2 /* TypeofEQNumber */,
            "boolean": 4 /* TypeofEQBoolean */,
            "symbol": 8 /* TypeofEQSymbol */,
            "undefined": 16384 /* EQUndefined */,
            "object": 16 /* TypeofEQObject */,
            "function": 32 /* TypeofEQFunction */
        });
        var typeofNEFacts = ts.createMapFromTemplate({
            "string": 128 /* TypeofNEString */,
            "number": 256 /* TypeofNENumber */,
            "boolean": 512 /* TypeofNEBoolean */,
            "symbol": 1024 /* TypeofNESymbol */,
            "undefined": 131072 /* NEUndefined */,
            "object": 2048 /* TypeofNEObject */,
            "function": 4096 /* TypeofNEFunction */
        });
        var typeofTypesByName = ts.createMapFromTemplate({
            "string": stringType,
            "number": numberType,
            "boolean": booleanType,
            "symbol": esSymbolType,
            "undefined": undefinedType
        });
        var typeofType = createTypeofType();
        var _jsxNamespace;
        var _jsxFactoryEntity;
        var _jsxElementPropertiesName;
        var _hasComputedJsxElementPropertiesName = false;
        var _jsxElementChildrenPropertyName;
        var _hasComputedJsxElementChildrenPropertyName = false;
        /** Things we lazy load from the JSX namespace */
        var jsxTypes = ts.createUnderscoreEscapedMap();
        var JsxNames = {
            JSX: "JSX",
            IntrinsicElements: "IntrinsicElements",
            ElementClass: "ElementClass",
            ElementAttributesPropertyNameContainer: "ElementAttributesProperty",
            ElementChildrenAttributeNameContainer: "ElementChildrenAttribute",
            Element: "Element",
            IntrinsicAttributes: "IntrinsicAttributes",
            IntrinsicClassAttributes: "IntrinsicClassAttributes"
        };
        var subtypeRelation = ts.createMap();
        var assignableRelation = ts.createMap();
        var comparableRelation = ts.createMap();
        var identityRelation = ts.createMap();
        var enumRelation = ts.createMap();
        // This is for caching the result of getSymbolDisplayBuilder. Do not access directly.
        var _displayBuilder;
        var TypeSystemPropertyName;
        (function (TypeSystemPropertyName) {
            TypeSystemPropertyName[TypeSystemPropertyName["Type"] = 0] = "Type";
            TypeSystemPropertyName[TypeSystemPropertyName["ResolvedBaseConstructorType"] = 1] = "ResolvedBaseConstructorType";
            TypeSystemPropertyName[TypeSystemPropertyName["DeclaredType"] = 2] = "DeclaredType";
            TypeSystemPropertyName[TypeSystemPropertyName["ResolvedReturnType"] = 3] = "ResolvedReturnType";
        })(TypeSystemPropertyName || (TypeSystemPropertyName = {}));
        var CheckMode;
        (function (CheckMode) {
            CheckMode[CheckMode["Normal"] = 0] = "Normal";
            CheckMode[CheckMode["SkipContextSensitive"] = 1] = "SkipContextSensitive";
            CheckMode[CheckMode["Inferential"] = 2] = "Inferential";
        })(CheckMode || (CheckMode = {}));
        var CallbackCheck;
        (function (CallbackCheck) {
            CallbackCheck[CallbackCheck["None"] = 0] = "None";
            CallbackCheck[CallbackCheck["Bivariant"] = 1] = "Bivariant";
            CallbackCheck[CallbackCheck["Strict"] = 2] = "Strict";
        })(CallbackCheck || (CallbackCheck = {}));
        var builtinGlobals = ts.createSymbolTable();
        builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
        var isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor);
        initializeTypeChecker();
        return checker;
        function getJsxNamespace() {
            if (!_jsxNamespace) {
                _jsxNamespace = "React";
                if (compilerOptions.jsxFactory) {
                    _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
                    if (_jsxFactoryEntity) {
                        _jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText;
                    }
                }
                else if (compilerOptions.reactNamespace) {
                    _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace);
                }
            }
            return _jsxNamespace;
        }
        function getEmitResolver(sourceFile, cancellationToken) {
            // Ensure we have all the type information in place for this file so that all the
            // emitter questions of this resolver will return the right information.
            getDiagnostics(sourceFile, cancellationToken);
            return emitResolver;
        }
        function error(location, message, arg0, arg1, arg2) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2);
            diagnostics.add(diagnostic);
        }
        function createSymbol(flags, name) {
            symbolCount++;
            var symbol = (new Symbol(flags | 33554432 /* Transient */, name));
            symbol.checkFlags = 0;
            return symbol;
        }
        function isTransientSymbol(symbol) {
            return (symbol.flags & 33554432 /* Transient */) !== 0;
        }
        function getExcludedSymbolFlags(flags) {
            var result = 0;
            if (flags & 2 /* BlockScopedVariable */)
                result |= 107455 /* BlockScopedVariableExcludes */;
            if (flags & 1 /* FunctionScopedVariable */)
                result |= 107454 /* FunctionScopedVariableExcludes */;
            if (flags & 4 /* Property */)
                result |= 0 /* PropertyExcludes */;
            if (flags & 8 /* EnumMember */)
                result |= 900095 /* EnumMemberExcludes */;
            if (flags & 16 /* Function */)
                result |= 106927 /* FunctionExcludes */;
            if (flags & 32 /* Class */)
                result |= 899519 /* ClassExcludes */;
            if (flags & 64 /* Interface */)
                result |= 792968 /* InterfaceExcludes */;
            if (flags & 256 /* RegularEnum */)
                result |= 899327 /* RegularEnumExcludes */;
            if (flags & 128 /* ConstEnum */)
                result |= 899967 /* ConstEnumExcludes */;
            if (flags & 512 /* ValueModule */)
                result |= 106639 /* ValueModuleExcludes */;
            if (flags & 8192 /* Method */)
                result |= 99263 /* MethodExcludes */;
            if (flags & 32768 /* GetAccessor */)
                result |= 41919 /* GetAccessorExcludes */;
            if (flags & 65536 /* SetAccessor */)
                result |= 74687 /* SetAccessorExcludes */;
            if (flags & 262144 /* TypeParameter */)
                result |= 530920 /* TypeParameterExcludes */;
            if (flags & 524288 /* TypeAlias */)
                result |= 793064 /* TypeAliasExcludes */;
            if (flags & 2097152 /* Alias */)
                result |= 2097152 /* AliasExcludes */;
            return result;
        }
        function recordMergedSymbol(target, source) {
            if (!source.mergeId) {
                source.mergeId = nextMergeId;
                nextMergeId++;
            }
            mergedSymbols[source.mergeId] = target;
        }
        function cloneSymbol(symbol) {
            var result = createSymbol(symbol.flags, symbol.escapedName);
            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
            result.parent = symbol.parent;
            if (symbol.valueDeclaration)
                result.valueDeclaration = symbol.valueDeclaration;
            if (symbol.constEnumOnlyModule)
                result.constEnumOnlyModule = true;
            if (symbol.members)
                result.members = ts.cloneMap(symbol.members);
            if (symbol.exports)
                result.exports = ts.cloneMap(symbol.exports);
            recordMergedSymbol(result, symbol);
            return result;
        }
        function mergeSymbol(target, source) {
            if (!(target.flags & getExcludedSymbolFlags(source.flags))) {
                if (source.flags & 512 /* ValueModule */ && target.flags & 512 /* ValueModule */ && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
                    // reset flag when merging instantiated module into value module that has only const enums
                    target.constEnumOnlyModule = false;
                }
                target.flags |= source.flags;
                if (source.valueDeclaration &&
                    (!target.valueDeclaration ||
                        (target.valueDeclaration.kind === 233 /* ModuleDeclaration */ && source.valueDeclaration.kind !== 233 /* ModuleDeclaration */))) {
                    // other kinds of value declarations take precedence over modules
                    target.valueDeclaration = source.valueDeclaration;
                }
                ts.addRange(target.declarations, source.declarations);
                if (source.members) {
                    if (!target.members)
                        target.members = ts.createSymbolTable();
                    mergeSymbolTable(target.members, source.members);
                }
                if (source.exports) {
                    if (!target.exports)
                        target.exports = ts.createSymbolTable();
                    mergeSymbolTable(target.exports, source.exports);
                }
                recordMergedSymbol(target, source);
            }
            else if (target.flags & 1024 /* NamespaceModule */) {
                error(ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
            }
            else {
                var message_2 = target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */
                    ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
                ts.forEach(source.declarations, function (node) {
                    error(ts.getNameOfDeclaration(node) || node, message_2, symbolToString(source));
                });
                ts.forEach(target.declarations, function (node) {
                    error(ts.getNameOfDeclaration(node) || node, message_2, symbolToString(source));
                });
            }
        }
        function mergeSymbolTable(target, source) {
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                if (!targetSymbol) {
                    target.set(id, sourceSymbol);
                }
                else {
                    if (!(targetSymbol.flags & 33554432 /* Transient */)) {
                        targetSymbol = cloneSymbol(targetSymbol);
                        target.set(id, targetSymbol);
                    }
                    mergeSymbol(targetSymbol, sourceSymbol);
                }
            });
        }
        function mergeModuleAugmentation(moduleName) {
            var moduleAugmentation = moduleName.parent;
            if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
                // this is a combined symbol for multiple augmentations within the same file.
                // its symbol already has accumulated information for all declarations
                // so we need to add it just once - do the work only for first declaration
                ts.Debug.assert(moduleAugmentation.symbol.declarations.length > 1);
                return;
            }
            if (ts.isGlobalScopeAugmentation(moduleAugmentation)) {
                mergeSymbolTable(globals, moduleAugmentation.symbol.exports);
            }
            else {
                // find a module that about to be augmented
                // do not validate names of augmentations that are defined in ambient context
                var moduleNotFoundError = !ts.isInAmbientContext(moduleName.parent.parent)
                    ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
                    : undefined;
                var mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
                if (!mainModule) {
                    return;
                }
                // obtain item referenced by 'export='
                mainModule = resolveExternalModuleSymbol(mainModule);
                if (mainModule.flags & 1920 /* Namespace */) {
                    // if module symbol has already been merged - it is safe to use it.
                    // otherwise clone it
                    mainModule = mainModule.flags & 33554432 /* Transient */ ? mainModule : cloneSymbol(mainModule);
                    mergeSymbol(mainModule, moduleAugmentation.symbol);
                }
                else {
                    // moduleName will be a StringLiteral since this is not `declare global`.
                    error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
                }
            }
        }
        function addToSymbolTable(target, source, message) {
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                if (targetSymbol) {
                    // Error on redeclarations
                    ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message));
                }
                else {
                    target.set(id, sourceSymbol);
                }
            });
            function addDeclarationDiagnostic(id, message) {
                return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); };
            }
        }
        function getSymbolLinks(symbol) {
            if (symbol.flags & 33554432 /* Transient */)
                return symbol;
            var id = getSymbolId(symbol);
            return symbolLinks[id] || (symbolLinks[id] = {});
        }
        function getNodeLinks(node) {
            var nodeId = getNodeId(node);
            return nodeLinks[nodeId] || (nodeLinks[nodeId] = { flags: 0 });
        }
        function getObjectFlags(type) {
            return type.flags & 32768 /* Object */ ? type.objectFlags : 0;
        }
        function isGlobalSourceFile(node) {
            return node.kind === 265 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
        }
        function getSymbol(symbols, name, meaning) {
            if (meaning) {
                var symbol = symbols.get(name);
                if (symbol) {
                    ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                    if (symbol.flags & meaning) {
                        return symbol;
                    }
                    if (symbol.flags & 2097152 /* Alias */) {
                        var target = resolveAlias(symbol);
                        // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
                        if (target === unknownSymbol || target.flags & meaning) {
                            return symbol;
                        }
                    }
                }
            }
            // return undefined if we can't find a symbol.
        }
        /**
         * Get symbols that represent parameter-property-declaration as parameter and as property declaration
         * @param parameter a parameterDeclaration node
         * @param parameterName a name of the parameter to get the symbols for.
         * @return a tuple of two symbols
         */
        function getSymbolsOfParameterPropertyDeclaration(parameter, parameterName) {
            var constructorDeclaration = parameter.parent;
            var classDeclaration = parameter.parent.parent;
            var parameterSymbol = getSymbol(constructorDeclaration.locals, parameterName, 107455 /* Value */);
            var propertySymbol = getSymbol(classDeclaration.symbol.members, parameterName, 107455 /* Value */);
            if (parameterSymbol && propertySymbol) {
                return [parameterSymbol, propertySymbol];
            }
            ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration");
        }
        function isBlockScopedNameDeclaredBeforeUse(declaration, usage) {
            var declarationFile = ts.getSourceFileOfNode(declaration);
            var useFile = ts.getSourceFileOfNode(usage);
            if (declarationFile !== useFile) {
                if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
                    (!compilerOptions.outFile && !compilerOptions.out) ||
                    isInTypeQuery(usage) ||
                    ts.isInAmbientContext(declaration)) {
                    // nodes are in different files and order cannot be determined
                    return true;
                }
                // declaration is after usage
                // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
                if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
                    return true;
                }
                var sourceFiles = host.getSourceFiles();
                return ts.indexOf(sourceFiles, declarationFile) <= ts.indexOf(sourceFiles, useFile);
            }
            if (declaration.pos <= usage.pos) {
                // declaration is before usage
                if (declaration.kind === 176 /* BindingElement */) {
                    // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
                    var errorBindingElement = ts.getAncestor(usage, 176 /* BindingElement */);
                    if (errorBindingElement) {
                        return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) ||
                            declaration.pos < errorBindingElement.pos;
                    }
                    // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
                    return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 226 /* VariableDeclaration */), usage);
                }
                else if (declaration.kind === 226 /* VariableDeclaration */) {
                    // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
                    return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage);
                }
                return true;
            }
            // declaration is after usage, but it can still be legal if usage is deferred:
            // 1. inside an export specifier
            // 2. inside a function
            // 3. inside an instance property initializer, a reference to a non-instance property
            // 4. inside a static property initializer, a reference to a static method in the same class
            // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
            // or if usage is in a type context:
            // 1. inside a type query (typeof in type position)
            if (usage.parent.kind === 246 /* ExportSpecifier */ || (usage.parent.kind === 243 /* ExportAssignment */ && usage.parent.isExportEquals)) {
                // export specifiers do not use the variable, they only make it available for use
                return true;
            }
            // When resolving symbols for exports, the `usage` location passed in can be the export site directly
            if (usage.kind === 243 /* ExportAssignment */ && usage.isExportEquals) {
                return true;
            }
            var container = ts.getEnclosingBlockScopeContainer(declaration);
            return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
            function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
                var container = ts.getEnclosingBlockScopeContainer(declaration);
                switch (declaration.parent.parent.kind) {
                    case 208 /* VariableStatement */:
                    case 214 /* ForStatement */:
                    case 216 /* ForOfStatement */:
                        // variable statement/for/for-of statement case,
                        // use site should not be inside variable declaration (initializer of declaration or binding element)
                        if (isSameScopeDescendentOf(usage, declaration, container)) {
                            return true;
                        }
                        break;
                }
                // ForIn/ForOf case - use site should not be used in expression part
                return ts.isForInOrOfStatement(declaration.parent.parent) && isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container);
            }
            function isUsedInFunctionOrInstanceProperty(usage, declaration, container) {
                return !!ts.findAncestor(usage, function (current) {
                    if (current === container) {
                        return "quit";
                    }
                    if (ts.isFunctionLike(current)) {
                        return true;
                    }
                    var initializerOfProperty = current.parent &&
                        current.parent.kind === 149 /* PropertyDeclaration */ &&
                        current.parent.initializer === current;
                    if (initializerOfProperty) {
                        if (ts.hasModifier(current.parent, 32 /* Static */)) {
                            if (declaration.kind === 151 /* MethodDeclaration */) {
                                return true;
                            }
                        }
                        else {
                            var isDeclarationInstanceProperty = declaration.kind === 149 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */);
                            if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) {
                                return true;
                            }
                        }
                    }
                });
            }
        }
        /**
         * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
         * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
         * the given name can be found.
         *
         * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters.
         */
        function resolveName(location, name, meaning, nameNotFoundMessage, nameArg, isUse, suggestedNameNotFoundMessage) {
            return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, getSymbol, suggestedNameNotFoundMessage);
        }
        function resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, lookup, suggestedNameNotFoundMessage) {
            var originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
            var result;
            var lastLocation;
            var lastNonBlockLocation;
            var propertyWithInvalidInitializer;
            var errorLocation = location;
            var grandparent;
            var isInExternalModule = false;
            loop: while (location) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = lookup(location.locals, name, meaning)) {
                        var useResult = true;
                        if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) {
                            // symbol lookup restrictions for function-like declarations
                            // - Type parameters of a function are in scope in the entire function declaration, including the parameter
                            //   list and return type. However, local types are only in scope in the function body.
                            // - parameters are only in the scope of function body
                            // This restriction does not apply to JSDoc comment types because they are parented
                            // at a higher level than type parameters would normally be
                            if (meaning & result.flags & 793064 /* Type */ && lastLocation.kind !== 275 /* JSDocComment */) {
                                useResult = result.flags & 262144 /* TypeParameter */
                                    // type parameters are visible in parameter list, return type and type parameter list
                                    ? lastLocation === location.type ||
                                        lastLocation.kind === 146 /* Parameter */ ||
                                        lastLocation.kind === 145 /* TypeParameter */
                                    // local types not visible outside the function body
                                    : false;
                            }
                            if (meaning & 107455 /* Value */ && result.flags & 1 /* FunctionScopedVariable */) {
                                // parameters are visible only inside function body, parameter list and return type
                                // technically for parameter list case here we might mix parameters and variables declared in function,
                                // however it is detected separately when checking initializers of parameters
                                // to make sure that they reference no variables declared after them.
                                useResult =
                                    lastLocation.kind === 146 /* Parameter */ ||
                                        (lastLocation === location.type &&
                                            result.valueDeclaration.kind === 146 /* Parameter */);
                            }
                        }
                        if (useResult) {
                            break loop;
                        }
                        else {
                            result = undefined;
                        }
                    }
                }
                switch (location.kind) {
                    case 265 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location))
                            break;
                        isInExternalModule = true;
                    // falls through
                    case 233 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports;
                        if (location.kind === 265 /* SourceFile */ || ts.isAmbientModule(location)) {
                            // It's an external module. First see if the module has an export default and if the local
                            // name of that export default matches.
                            if (result = moduleExports.get("default")) {
                                var localSymbol = ts.getLocalSymbolForExportDefault(result);
                                if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
                                    break loop;
                                }
                                result = undefined;
                            }
                            // Because of module/namespace merging, a module's exports are in scope,
                            // yet we never want to treat an export specifier as putting a member in scope.
                            // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
                            // Two things to note about this:
                            //     1. We have to check this without calling getSymbol. The problem with calling getSymbol
                            //        on an export specifier is that it might find the export specifier itself, and try to
                            //        resolve it as an alias. This will cause the checker to consider the export specifier
                            //        a circular alias reference when it might not be.
                            //     2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
                            //        an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
                            //        which is not the desired behavior.
                            var moduleExport = moduleExports.get(name);
                            if (moduleExport &&
                                moduleExport.flags === 2097152 /* Alias */ &&
                                ts.getDeclarationOfKind(moduleExport, 246 /* ExportSpecifier */)) {
                                break;
                            }
                        }
                        if (result = lookup(moduleExports, name, meaning & 2623475 /* ModuleMember */)) {
                            break loop;
                        }
                        break;
                    case 232 /* EnumDeclaration */:
                        if (result = lookup(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                        // TypeScript 1.0 spec (April 2014): 8.4.1
                        // Initializer expressions for instance member variables are evaluated in the scope
                        // of the class constructor body but are not permitted to reference parameters or
                        // local variables of the constructor. This effectively means that entities from outer scopes
                        // by the same name as a constructor parameter or local variable are inaccessible
                        // in initializer expressions for instance member variables.
                        if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32 /* Static */)) {
                            var ctor = findConstructorDeclaration(location.parent);
                            if (ctor && ctor.locals) {
                                if (lookup(ctor.locals, name, meaning & 107455 /* Value */)) {
                                    // Remember the property node, it will be used later to report appropriate error
                                    propertyWithInvalidInitializer = location;
                                }
                            }
                        }
                        break;
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 230 /* InterfaceDeclaration */:
                        if (result = lookup(getSymbolOfNode(location).members, name, meaning & 793064 /* Type */)) {
                            if (!isTypeParameterSymbolDeclaredInContainer(result, location)) {
                                // ignore type parameters not declared in this container
                                result = undefined;
                                break;
                            }
                            if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) {
                                // TypeScript 1.0 spec (April 2014): 3.4.1
                                // The scope of a type parameter extends over the entire declaration with which the type
                                // parameter list is associated, with the exception of static member declarations in classes.
                                error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
                                return undefined;
                            }
                            break loop;
                        }
                        if (location.kind === 199 /* ClassExpression */ && meaning & 32 /* Class */) {
                            var className = location.name;
                            if (className && name === className.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 201 /* ExpressionWithTypeArguments */:
                        // The type parameters of a class are not in scope in the base class expression.
                        if (lastLocation === location.expression && location.parent.token === 85 /* ExtendsKeyword */) {
                            var container = location.parent.parent;
                            if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & 793064 /* Type */))) {
                                if (nameNotFoundMessage) {
                                    error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
                                }
                                return undefined;
                            }
                        }
                        break;
                    // It is not legal to reference a class's own type parameters from a computed property name that
                    // belongs to the class. For example:
                    //
                    //   function foo<T>() { return '' }
                    //   class C<T> { // <-- Class's own type parameter T
                    //       [foo<T>()]() { } // <-- Reference to T from class's own computed property
                    //   }
                    //
                    case 144 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 230 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = lookup(getSymbolOfNode(grandparent).members, name, meaning & 793064 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                    case 152 /* Constructor */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    case 228 /* FunctionDeclaration */:
                    case 187 /* ArrowFunction */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 186 /* FunctionExpression */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        if (meaning & 16 /* Function */) {
                            var functionName = location.name;
                            if (functionName && name === functionName.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 147 /* Decorator */:
                        // Decorators are resolved at the class declaration. Resolving at the parameter
                        // or member would result in looking up locals in the method.
                        //
                        //   function y() {}
                        //   class C {
                        //       method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
                        //   }
                        //
                        if (location.parent && location.parent.kind === 146 /* Parameter */) {
                            location = location.parent;
                        }
                        //
                        //   function y() {}
                        //   class C {
                        //       @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
                        //   }
                        //
                        if (location.parent && ts.isClassElement(location.parent)) {
                            location = location.parent;
                        }
                        break;
                }
                if (location.kind !== 207 /* Block */) {
                    lastNonBlockLocation = location;
                }
                lastLocation = location;
                location = location.parent;
            }
            // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
            // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself.
            // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
            if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) {
                result.isReferenced = true;
            }
            if (!result) {
                if (lastLocation) {
                    ts.Debug.assert(lastLocation.kind === 265 /* SourceFile */);
                    if (lastLocation.commonJsModuleIndicator && name === "exports") {
                        return lastLocation.symbol;
                    }
                }
                result = lookup(globals, name, meaning);
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    if (!errorLocation ||
                        !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
                            !checkAndReportErrorForExtendingInterface(errorLocation) &&
                            !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) {
                        var suggestion = void 0;
                        if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
                            suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning);
                            if (suggestion) {
                                error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestion);
                            }
                        }
                        if (!suggestion) {
                            error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
                        }
                        suggestionCount++;
                    }
                }
                return undefined;
            }
            // Perform extra checks only if error reporting was requested
            if (nameNotFoundMessage) {
                if (propertyWithInvalidInitializer) {
                    // We have a match, but the reference occurred within a property initializer and the identifier also binds
                    // to a local variable in the constructor where the code will be emitted.
                    var propertyName = propertyWithInvalidInitializer.name;
                    error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg));
                    return undefined;
                }
                // Only check for block-scoped variable if we have an error location and are looking for the
                // name with variable meaning
                //      For example,
                //          declare module foo {
                //              interface bar {}
                //          }
                //      const foo/*1*/: foo/*2*/.bar;
                // The foo at /*1*/ and /*2*/ will share same symbol with two meanings:
                // block-scoped variable and namespace module. However, only when we
                // try to resolve name in /*1*/ which is used in variable position,
                // we want to check for block-scoped
                if (errorLocation &&
                    (meaning & 2 /* BlockScopedVariable */ ||
                        ((meaning & 32 /* Class */ || meaning & 384 /* Enum */) && (meaning & 107455 /* Value */) === 107455 /* Value */))) {
                    var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
                    if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */ || exportOrLocalSymbol.flags & 32 /* Class */ || exportOrLocalSymbol.flags & 384 /* Enum */) {
                        checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
                    }
                }
                // If we're in an external module, we can't reference value symbols created from UMD export declarations
                if (result && isInExternalModule && (meaning & 107455 /* Value */) === 107455 /* Value */) {
                    var decls = result.declarations;
                    if (decls && decls.length === 1 && decls[0].kind === 236 /* NamespaceExportDeclaration */) {
                        error(errorLocation, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name));
                    }
                }
            }
            return result;
        }
        function diagnosticName(nameArg) {
            return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg) : ts.declarationNameToString(nameArg);
        }
        function isTypeParameterSymbolDeclaredInContainer(symbol, container) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.kind === 145 /* TypeParameter */ && decl.parent === container) {
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) {
            if ((errorLocation.kind === 71 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) {
                return false;
            }
            var container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ true);
            var location = container;
            while (location) {
                if (ts.isClassLike(location.parent)) {
                    var classSymbol = getSymbolOfNode(location.parent);
                    if (!classSymbol) {
                        break;
                    }
                    // Check to see if a static member exists.
                    var constructorType = getTypeOfSymbol(classSymbol);
                    if (getPropertyOfType(constructorType, name)) {
                        error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol));
                        return true;
                    }
                    // No static member is present.
                    // Check if we're in an instance method and look for a relevant instance member.
                    if (location === container && !ts.hasModifier(location, 32 /* Static */)) {
                        var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType;
                        if (getPropertyOfType(instanceType, name)) {
                            error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg));
                            return true;
                        }
                    }
                }
                location = location.parent;
            }
            return false;
        }
        function checkAndReportErrorForExtendingInterface(errorLocation) {
            var expression = getEntityNameForExtendingInterface(errorLocation);
            var isError = !!(expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true));
            if (isError) {
                error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression));
            }
            return isError;
        }
        /**
         * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression,
         * but returns undefined if that expression is not an EntityNameExpression.
         */
        function getEntityNameForExtendingInterface(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                case 179 /* PropertyAccessExpression */:
                    return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
                case 201 /* ExpressionWithTypeArguments */:
                    if (ts.isEntityNameExpression(node.expression)) {
                        return node.expression;
                    }
                // falls through
                default:
                    return undefined;
            }
        }
        function checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) {
            if (meaning === 1920 /* Namespace */) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 793064 /* Type */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                var parent = errorLocation.parent;
                if (symbol) {
                    if (ts.isQualifiedName(parent)) {
                        ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace");
                        var propName = parent.right.escapedText;
                        var propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName);
                        if (propType) {
                            error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName));
                            return true;
                        }
                    }
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) {
            if (meaning & (107455 /* Value */ & ~1024 /* NamespaceModule */)) {
                if (name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never") {
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
                var symbol = resolveSymbol(resolveName(errorLocation, name, 793064 /* Type */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1024 /* NamespaceModule */)) {
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) {
            if (meaning & (107455 /* Value */ & ~1024 /* NamespaceModule */ & ~793064 /* Type */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            else if (meaning & (793064 /* Type */ & ~1024 /* NamespaceModule */ & ~107455 /* Value */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~793064 /* Type */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkResolvedBlockScopedVariable(result, errorLocation) {
            ts.Debug.assert(!!(result.flags & 2 /* BlockScopedVariable */ || result.flags & 32 /* Class */ || result.flags & 384 /* Enum */));
            // Block-scoped variables cannot be used before their definition
            var declaration = ts.forEach(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === 232 /* EnumDeclaration */) ? d : undefined; });
            ts.Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined");
            if (!ts.isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
                if (result.flags & 2 /* BlockScopedVariable */) {
                    error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)));
                }
                else if (result.flags & 32 /* Class */) {
                    error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)));
                }
                else if (result.flags & 256 /* RegularEnum */) {
                    error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)));
                }
            }
        }
        /* Starting from 'initial' node walk up the parent chain until 'stopAt' node is reached.
         * If at any point current node is equal to 'parent' node - return true.
         * Return false if 'stopAt' node is reached or isFunctionLike(current) === true.
         */
        function isSameScopeDescendentOf(initial, parent, stopAt) {
            return parent && !!ts.findAncestor(initial, function (n) { return n === stopAt || ts.isFunctionLike(n) ? "quit" : n === parent; });
        }
        function getAnyImportSyntax(node) {
            switch (node.kind) {
                case 237 /* ImportEqualsDeclaration */:
                    return node;
                case 239 /* ImportClause */:
                    return node.parent;
                case 240 /* NamespaceImport */:
                    return node.parent.parent;
                case 242 /* ImportSpecifier */:
                    return node.parent.parent.parent;
                default:
                    return undefined;
            }
        }
        function getDeclarationOfAliasSymbol(symbol) {
            return ts.find(symbol.declarations, ts.isAliasSymbolDeclaration);
        }
        function getTargetOfImportEqualsDeclaration(node, dontResolveAlias) {
            if (node.moduleReference.kind === 248 /* ExternalModuleReference */) {
                return resolveExternalModuleSymbol(resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node)));
            }
            return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
        }
        function getTargetOfImportClause(node, dontResolveAlias) {
            var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
            if (moduleSymbol) {
                var exportDefaultSymbol = void 0;
                if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                    exportDefaultSymbol = moduleSymbol;
                }
                else {
                    var exportValue = moduleSymbol.exports.get("export=");
                    exportDefaultSymbol = exportValue
                        ? getPropertyOfType(getTypeOfSymbol(exportValue), "default")
                        : resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias);
                }
                if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
                    error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
                }
                else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
                    return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                }
                return exportDefaultSymbol;
            }
        }
        function getTargetOfNamespaceImport(node, dontResolveAlias) {
            var moduleSpecifier = node.parent.parent.moduleSpecifier;
            return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
        }
        // This function creates a synthetic symbol that combines the value side of one symbol with the
        // type/namespace side of another symbol. Consider this example:
        //
        //   declare module graphics {
        //       interface Point {
        //           x: number;
        //           y: number;
        //       }
        //   }
        //   declare var graphics: {
        //       Point: new (x: number, y: number) => graphics.Point;
        //   }
        //   declare module "graphics" {
        //       export = graphics;
        //   }
        //
        // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point'
        // property with the type/namespace side interface 'Point'.
        function combineValueAndTypeSymbols(valueSymbol, typeSymbol) {
            if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) {
                return unknownSymbol;
            }
            if (valueSymbol.flags & (793064 /* Type */ | 1920 /* Namespace */)) {
                return valueSymbol;
            }
            var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
            result.declarations = ts.concatenate(valueSymbol.declarations, typeSymbol.declarations);
            result.parent = valueSymbol.parent || typeSymbol.parent;
            if (valueSymbol.valueDeclaration)
                result.valueDeclaration = valueSymbol.valueDeclaration;
            if (typeSymbol.members)
                result.members = typeSymbol.members;
            if (valueSymbol.exports)
                result.exports = valueSymbol.exports;
            return result;
        }
        function getExportOfModule(symbol, name, dontResolveAlias) {
            if (symbol.flags & 1536 /* Module */) {
                return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
            }
        }
        function getPropertyOfVariable(symbol, name) {
            if (symbol.flags & 3 /* Variable */) {
                var typeAnnotation = symbol.valueDeclaration.type;
                if (typeAnnotation) {
                    return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
                }
            }
        }
        function getExternalModuleMember(node, specifier, dontResolveAlias) {
            var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
            var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
            if (targetSymbol) {
                var name = specifier.propertyName || specifier.name;
                if (name.escapedText) {
                    if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                        return moduleSymbol;
                    }
                    var symbolFromVariable = void 0;
                    // First check if module was specified with "export=". If so, get the member from the resolved type
                    if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=")) {
                        symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
                    }
                    else {
                        symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText);
                    }
                    // if symbolFromVariable is export - get its final target
                    symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
                    var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias);
                    // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
                    if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") {
                        symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                    }
                    var symbol = symbolFromModule && symbolFromVariable ?
                        combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
                        symbolFromModule || symbolFromVariable;
                    if (!symbol) {
                        error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name));
                    }
                    return symbol;
                }
            }
        }
        function getTargetOfImportSpecifier(node, dontResolveAlias) {
            return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
        }
        function getTargetOfNamespaceExportDeclaration(node, dontResolveAlias) {
            return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
        }
        function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node, dontResolveAlias) :
                resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias);
        }
        function getTargetOfExportAssignment(node, dontResolveAlias) {
            return resolveEntityName(node.expression, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
        }
        function getTargetOfAliasDeclaration(node, dontRecursivelyResolve) {
            switch (node.kind) {
                case 237 /* ImportEqualsDeclaration */:
                    return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve);
                case 239 /* ImportClause */:
                    return getTargetOfImportClause(node, dontRecursivelyResolve);
                case 240 /* NamespaceImport */:
                    return getTargetOfNamespaceImport(node, dontRecursivelyResolve);
                case 242 /* ImportSpecifier */:
                    return getTargetOfImportSpecifier(node, dontRecursivelyResolve);
                case 246 /* ExportSpecifier */:
                    return getTargetOfExportSpecifier(node, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, dontRecursivelyResolve);
                case 243 /* ExportAssignment */:
                    return getTargetOfExportAssignment(node, dontRecursivelyResolve);
                case 236 /* NamespaceExportDeclaration */:
                    return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve);
            }
        }
        /**
         * Indicates that a symbol is an alias that does not merge with a local declaration.
         */
        function isNonLocalAlias(symbol, excludes) {
            if (excludes === void 0) { excludes = 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */; }
            return symbol && (symbol.flags & (2097152 /* Alias */ | excludes)) === 2097152 /* Alias */;
        }
        function resolveSymbol(symbol, dontResolveAlias) {
            var shouldResolve = !dontResolveAlias && isNonLocalAlias(symbol);
            return shouldResolve ? resolveAlias(symbol) : symbol;
        }
        function resolveAlias(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.target) {
                links.target = resolvingSymbol;
                var node = getDeclarationOfAliasSymbol(symbol);
                ts.Debug.assert(!!node);
                var target = getTargetOfAliasDeclaration(node);
                if (links.target === resolvingSymbol) {
                    links.target = target || unknownSymbol;
                }
                else {
                    error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
                }
            }
            else if (links.target === resolvingSymbol) {
                links.target = unknownSymbol;
            }
            return links.target;
        }
        function markExportAsReferenced(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            if (target) {
                var markAlias = target === unknownSymbol ||
                    ((target.flags & 107455 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target));
                if (markAlias) {
                    markAliasSymbolAsReferenced(symbol);
                }
            }
        }
        // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
        // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
        // the alias as an expression (which recursively takes us back here if the target references another alias).
        function markAliasSymbolAsReferenced(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.referenced) {
                links.referenced = true;
                var node = getDeclarationOfAliasSymbol(symbol);
                ts.Debug.assert(!!node);
                if (node.kind === 243 /* ExportAssignment */) {
                    // export default <symbol>
                    checkExpressionCached(node.expression);
                }
                else if (node.kind === 246 /* ExportSpecifier */) {
                    // export { <symbol> } or export { <symbol> as foo }
                    checkExpressionCached(node.propertyName || node.name);
                }
                else if (ts.isInternalModuleImportEqualsDeclaration(node)) {
                    // import foo = <symbol>
                    checkExpressionCached(node.moduleReference);
                }
            }
        }
        // This function is only for imports with entity names
        function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, dontResolveAlias) {
            // There are three things we might try to look for. In the following examples,
            // the search term is enclosed in |...|:
            //
            //     import a = |b|; // Namespace
            //     import a = |b.c|; // Value, type, namespace
            //     import a = |b.c|.d; // Namespace
            if (entityName.kind === 71 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            // Check for case 1 and 3 in the above example
            if (entityName.kind === 71 /* Identifier */ || entityName.parent.kind === 143 /* QualifiedName */) {
                return resolveEntityName(entityName, 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
            else {
                // Case 2 in above example
                // entityName.kind could be a QualifiedName or a Missing identifier
                ts.Debug.assert(entityName.parent.kind === 237 /* ImportEqualsDeclaration */);
                return resolveEntityName(entityName, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
        }
        function getFullyQualifiedName(symbol) {
            return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol);
        }
        /**
         * Resolves a qualified name and any involved aliases.
         */
        function resolveEntityName(name, meaning, ignoreErrors, dontResolveAlias, location) {
            if (ts.nodeIsMissing(name)) {
                return undefined;
            }
            var symbol;
            if (name.kind === 71 /* Identifier */) {
                var message = meaning === 1920 /* Namespace */ ? ts.Diagnostics.Cannot_find_namespace_0 : ts.Diagnostics.Cannot_find_name_0;
                symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors ? undefined : message, name, /*isUse*/ true);
                if (!symbol) {
                    return undefined;
                }
            }
            else if (name.kind === 143 /* QualifiedName */ || name.kind === 179 /* PropertyAccessExpression */) {
                var left = void 0;
                if (name.kind === 143 /* QualifiedName */) {
                    left = name.left;
                }
                else if (name.kind === 179 /* PropertyAccessExpression */ &&
                    (name.expression.kind === 185 /* ParenthesizedExpression */ || ts.isEntityNameExpression(name.expression))) {
                    left = name.expression;
                }
                else {
                    // If the expression in property-access expression is not entity-name or parenthsizedExpression (e.g. it is a call expression), it won't be able to successfully resolve the name.
                    // This is the case when we are trying to do any language service operation in heritage clauses. By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression
                    // will attempt to checkPropertyAccessExpression to resolve symbol.
                    // i.e class C extends foo()./*do language service operation here*/B {}
                    return undefined;
                }
                var right = name.kind === 143 /* QualifiedName */ ? name.right : name.name;
                var namespace = resolveEntityName(left, 1920 /* Namespace */, ignoreErrors, /*dontResolveAlias*/ false, location);
                if (!namespace || ts.nodeIsMissing(right)) {
                    return undefined;
                }
                else if (namespace === unknownSymbol) {
                    return namespace;
                }
                symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning);
                if (!symbol) {
                    if (!ignoreErrors) {
                        error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
                    }
                    return undefined;
                }
            }
            else if (name.kind === 185 /* ParenthesizedExpression */) {
                // If the expression in parenthesizedExpression is not an entity-name (e.g. it is a call expression), it won't be able to successfully resolve the name.
                // This is the case when we are trying to do any language service operation in heritage clauses.
                // By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression will attempt to checkPropertyAccessExpression to resolve symbol.
                // i.e class C extends foo()./*do language service operation here*/B {}
                return ts.isEntityNameExpression(name.expression) ?
                    resolveEntityName(name.expression, meaning, ignoreErrors, dontResolveAlias, location) :
                    undefined;
            }
            else {
                ts.Debug.assertNever(name, "Unknown entity name kind.");
            }
            ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
            return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
        }
        function resolveExternalModuleName(location, moduleReferenceExpression) {
            return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ts.Diagnostics.Cannot_find_module_0);
        }
        function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            if (moduleReferenceExpression.kind !== 9 /* StringLiteral */ && moduleReferenceExpression.kind !== 13 /* NoSubstitutionTemplateLiteral */) {
                return;
            }
            var moduleReferenceLiteral = moduleReferenceExpression;
            return resolveExternalModule(location, moduleReferenceLiteral.text, moduleNotFoundError, moduleReferenceLiteral, isForAugmentation);
        }
        function resolveExternalModule(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            if (moduleReference === undefined) {
                return;
            }
            if (ts.startsWith(moduleReference, "@types/")) {
                var diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1;
                var withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/");
                error(errorNode, diag, withoutAtTypePrefix, moduleReference);
            }
            var ambientModule = tryFindAmbientModule(moduleReference, /*withAugmentations*/ true);
            if (ambientModule) {
                return ambientModule;
            }
            var resolvedModule = ts.getResolvedModule(ts.getSourceFileOfNode(location), moduleReference);
            var resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule);
            var sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
            if (sourceFile) {
                if (sourceFile.symbol) {
                    // merged symbol is module declaration symbol combined with all augmentations
                    return getMergedSymbol(sourceFile.symbol);
                }
                if (moduleNotFoundError) {
                    // report errors only if it was requested
                    error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
                }
                return undefined;
            }
            if (patternAmbientModules) {
                var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleReference);
                if (pattern) {
                    return getMergedSymbol(pattern.symbol);
                }
            }
            // May be an untyped module. If so, ignore resolutionDiagnostic.
            if (resolvedModule && !ts.extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
                if (isForAugmentation) {
                    var diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
                    error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
                }
                else if (noImplicitAny && moduleNotFoundError) {
                    var errorInfo = !resolvedModule.isExternalLibraryImport ? undefined : ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference);
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedModule.resolvedFileName);
                    diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo));
                }
                // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
                return undefined;
            }
            if (moduleNotFoundError) {
                // report errors only if it was requested
                if (resolutionDiagnostic) {
                    error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    var tsExtension = ts.tryExtractTypeScriptExtension(moduleReference);
                    if (tsExtension) {
                        var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
                        error(errorNode, diag, tsExtension, ts.removeExtension(moduleReference, tsExtension));
                    }
                    else {
                        error(errorNode, moduleNotFoundError, moduleReference);
                    }
                }
            }
            return undefined;
        }
        // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
        // and an external module with no 'export =' declaration resolves to the module itself.
        function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) {
            return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias)) || moduleSymbol;
        }
        // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
        // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
        // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
        function resolveESModuleSymbol(moduleSymbol, moduleReferenceExpression, dontResolveAlias) {
            var symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
            if (!dontResolveAlias && symbol && !(symbol.flags & (1536 /* Module */ | 3 /* Variable */))) {
                error(moduleReferenceExpression, ts.Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol));
            }
            return symbol;
        }
        function hasExportAssignmentSymbol(moduleSymbol) {
            return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined;
        }
        function getExportsOfModuleAsArray(moduleSymbol) {
            return symbolsToArray(getExportsOfModule(moduleSymbol));
        }
        function getExportsAndPropertiesOfModule(moduleSymbol) {
            var exports = getExportsOfModuleAsArray(moduleSymbol);
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals !== moduleSymbol) {
                ts.addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals)));
            }
            return exports;
        }
        function tryGetMemberInModuleExports(memberName, moduleSymbol) {
            var symbolTable = getExportsOfModule(moduleSymbol);
            if (symbolTable) {
                return symbolTable.get(memberName);
            }
        }
        function tryGetMemberInModuleExportsAndProperties(memberName, moduleSymbol) {
            var symbol = tryGetMemberInModuleExports(memberName, moduleSymbol);
            if (!symbol) {
                var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
                if (exportEquals !== moduleSymbol) {
                    return getPropertyOfType(getTypeOfSymbol(exportEquals), memberName);
                }
            }
            return symbol;
        }
        function getExportsOfSymbol(symbol) {
            return symbol.flags & 1536 /* Module */ ? getExportsOfModule(symbol) : symbol.exports || emptySymbols;
        }
        function getExportsOfModule(moduleSymbol) {
            var links = getSymbolLinks(moduleSymbol);
            return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol));
        }
        /**
         * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
         * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
         */
        function extendExportSymbols(target, source, lookupTable, exportNode) {
            source && source.forEach(function (sourceSymbol, id) {
                if (id === "default")
                    return;
                var targetSymbol = target.get(id);
                if (!targetSymbol) {
                    target.set(id, sourceSymbol);
                    if (lookupTable && exportNode) {
                        lookupTable.set(id, {
                            specifierText: ts.getTextOfNode(exportNode.moduleSpecifier)
                        });
                    }
                }
                else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) {
                    var collisionTracker = lookupTable.get(id);
                    if (!collisionTracker.exportsWithDuplicate) {
                        collisionTracker.exportsWithDuplicate = [exportNode];
                    }
                    else {
                        collisionTracker.exportsWithDuplicate.push(exportNode);
                    }
                }
            });
        }
        function getExportsOfModuleWorker(moduleSymbol) {
            var visitedSymbols = [];
            // A module defined by an 'export=' consists on one export that needs to be resolved
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            return visit(moduleSymbol) || emptySymbols;
            // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
            // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
            function visit(symbol) {
                if (!(symbol && symbol.flags & 1952 /* HasExports */ && ts.pushIfUnique(visitedSymbols, symbol))) {
                    return;
                }
                var symbols = ts.cloneMap(symbol.exports);
                // All export * declarations are collected in an __export symbol by the binder
                var exportStars = symbol.exports.get("__export" /* ExportStar */);
                if (exportStars) {
                    var nestedSymbols = ts.createSymbolTable();
                    var lookupTable_1 = ts.createMap();
                    for (var _i = 0, _a = exportStars.declarations; _i < _a.length; _i++) {
                        var node = _a[_i];
                        var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
                        var exportedSymbols = visit(resolvedModule);
                        extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable_1, node);
                    }
                    lookupTable_1.forEach(function (_a, id) {
                        var exportsWithDuplicate = _a.exportsWithDuplicate;
                        // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
                        if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) {
                            return;
                        }
                        for (var _i = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _i < exportsWithDuplicate_1.length; _i++) {
                            var node = exportsWithDuplicate_1[_i];
                            diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable_1.get(id).specifierText, ts.unescapeLeadingUnderscores(id)));
                        }
                    });
                    extendExportSymbols(symbols, nestedSymbols);
                }
                return symbols;
            }
        }
        function getMergedSymbol(symbol) {
            var merged;
            return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
        }
        function getSymbolOfNode(node) {
            return getMergedSymbol(node.symbol);
        }
        function getParentOfSymbol(symbol) {
            return getMergedSymbol(symbol.parent);
        }
        function getExportSymbolOfValueSymbolIfExported(symbol) {
            return symbol && (symbol.flags & 1048576 /* ExportValue */) !== 0
                ? getMergedSymbol(symbol.exportSymbol)
                : symbol;
        }
        function symbolIsValue(symbol) {
            return !!(symbol.flags & 107455 /* Value */ || symbol.flags & 2097152 /* Alias */ && resolveAlias(symbol).flags & 107455 /* Value */);
        }
        function findConstructorDeclaration(node) {
            var members = node.members;
            for (var _i = 0, members_2 = members; _i < members_2.length; _i++) {
                var member = members_2[_i];
                if (member.kind === 152 /* Constructor */ && ts.nodeIsPresent(member.body)) {
                    return member;
                }
            }
        }
        function createType(flags) {
            var result = new Type(checker, flags);
            typeCount++;
            result.id = typeCount;
            return result;
        }
        function createIntrinsicType(kind, intrinsicName) {
            var type = createType(kind);
            type.intrinsicName = intrinsicName;
            return type;
        }
        function createBooleanType(trueFalseTypes) {
            var type = getUnionType(trueFalseTypes);
            type.flags |= 8 /* Boolean */;
            type.intrinsicName = "boolean";
            return type;
        }
        function createObjectType(objectFlags, symbol) {
            var type = createType(32768 /* Object */);
            type.objectFlags = objectFlags;
            type.symbol = symbol;
            return type;
        }
        function createTypeofType() {
            return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getLiteralType));
        }
        // A reserved member name starts with two underscores, but the third character cannot be an underscore
        // or the @ symbol. A third underscore indicates an escaped form of an identifer that started
        // with at least two underscores. The @ character indicates that the name is denoted by a well known ES
        // Symbol instance.
        function isReservedMemberName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) !== 95 /* _ */ &&
                name.charCodeAt(2) !== 64 /* at */;
        }
        function getNamedMembers(members) {
            var result;
            members.forEach(function (symbol, id) {
                if (!isReservedMemberName(id)) {
                    if (!result)
                        result = [];
                    if (symbolIsValue(symbol)) {
                        result.push(symbol);
                    }
                }
            });
            return result || ts.emptyArray;
        }
        function setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            type.members = members;
            type.properties = getNamedMembers(members);
            type.callSignatures = callSignatures;
            type.constructSignatures = constructSignatures;
            if (stringIndexInfo)
                type.stringIndexInfo = stringIndexInfo;
            if (numberIndexInfo)
                type.numberIndexInfo = numberIndexInfo;
            return type;
        }
        function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            return setStructuredTypeMembers(createObjectType(16 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function forEachSymbolTableInScope(enclosingDeclaration, callback) {
            var result;
            for (var location = enclosingDeclaration; location; location = location.parent) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = callback(location.locals)) {
                        return result;
                    }
                }
                switch (location.kind) {
                    case 265 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location)) {
                            break;
                        }
                    // falls through
                    case 233 /* ModuleDeclaration */:
                        if (result = callback(getSymbolOfNode(location).exports)) {
                            return result;
                        }
                        break;
                }
            }
            return callback(globals);
        }
        function getQualifiedLeftMeaning(rightMeaning) {
            // If we are looking in value space, the parent meaning is value, other wise it is namespace
            return rightMeaning === 107455 /* Value */ ? 107455 /* Value */ : 1920 /* Namespace */;
        }
        function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing) {
            if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) {
                return undefined;
            }
            var visitedSymbolTables = [];
            return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
            function getAccessibleSymbolChainFromSymbolTable(symbols) {
                if (!ts.pushIfUnique(visitedSymbolTables, symbols)) {
                    return undefined;
                }
                var result = trySymbolTable(symbols);
                visitedSymbolTables.pop();
                return result;
            }
            function canQualifySymbol(symbolFromSymbolTable, meaning) {
                // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
                return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) ||
                    // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
                    !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
            }
            function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol) {
                return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
                    // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
                    // and if symbolFromSymbolTable or alias resolution matches the symbol,
                    // check the symbol can be qualified, it is only then this symbol is accessible
                    !ts.some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
                    canQualifySymbol(symbolFromSymbolTable, meaning);
            }
            function isUMDExportSymbol(symbol) {
                return symbol && symbol.declarations && symbol.declarations[0] && ts.isNamespaceExportDeclaration(symbol.declarations[0]);
            }
            function trySymbolTable(symbols) {
                // If symbol is directly available by its name in the symbol table
                if (isAccessible(symbols.get(symbol.escapedName))) {
                    return [symbol];
                }
                // Check if symbol is any of the alias
                return ts.forEachEntry(symbols, function (symbolFromSymbolTable) {
                    if (symbolFromSymbolTable.flags & 2097152 /* Alias */
                        && symbolFromSymbolTable.escapedName !== "export="
                        && !ts.getDeclarationOfKind(symbolFromSymbolTable, 246 /* ExportSpecifier */)
                        && !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration)))
                        // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
                        && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration))) {
                        var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
                        if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
                            return [symbolFromSymbolTable];
                        }
                        // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
                        // but only if the symbolFromSymbolTable can be qualified
                        var accessibleSymbolsFromExports = resolvedImportedSymbol.exports ? getAccessibleSymbolChainFromSymbolTable(resolvedImportedSymbol.exports) : undefined;
                        if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
                            return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
                        }
                    }
                });
            }
        }
        function needsQualification(symbol, enclosingDeclaration, meaning) {
            var qualify = false;
            forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) {
                // If symbol of this name is not available in the symbol table we are ok
                var symbolFromSymbolTable = symbolTable.get(symbol.escapedName);
                if (!symbolFromSymbolTable) {
                    // Continue to the next symbol table
                    return false;
                }
                // If the symbol with this name is present it should refer to the symbol
                if (symbolFromSymbolTable === symbol) {
                    // No need to qualify
                    return true;
                }
                // Qualify if the symbol from symbol table has same meaning as expected
                symbolFromSymbolTable = (symbolFromSymbolTable.flags & 2097152 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 246 /* ExportSpecifier */)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable;
                if (symbolFromSymbolTable.flags & meaning) {
                    qualify = true;
                    return true;
                }
                // Continue to the next symbol table
                return false;
            });
            return qualify;
        }
        function isPropertyOrMethodDeclarationSymbol(symbol) {
            if (symbol.declarations && symbol.declarations.length) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    switch (declaration.kind) {
                        case 149 /* PropertyDeclaration */:
                        case 151 /* MethodDeclaration */:
                        case 153 /* GetAccessor */:
                        case 154 /* SetAccessor */:
                            continue;
                        default:
                            return false;
                    }
                }
                return true;
            }
            return false;
        }
        function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        /**
         * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
         *
         * @param symbol a Symbol to check if accessible
         * @param enclosingDeclaration a Node containing reference to the symbol
         * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
         * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
         */
        function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) {
            if (symbol && enclosingDeclaration && !(symbol.flags & 262144 /* TypeParameter */)) {
                var initialSymbol = symbol;
                var meaningToLook = meaning;
                while (symbol) {
                    // Symbol is accessible if it by itself is accessible
                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaningToLook, /*useOnlyExternalAliasing*/ false);
                    if (accessibleSymbolChain) {
                        var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible);
                        if (!hasAccessibleDeclarations) {
                            return {
                                accessibility: 1 /* NotAccessible */,
                                errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                                errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, 1920 /* Namespace */) : undefined,
                            };
                        }
                        return hasAccessibleDeclarations;
                    }
                    // If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
                    // It could be a qualified symbol and hence verify the path
                    // e.g.:
                    // module m {
                    //     export class c {
                    //     }
                    // }
                    // const x: typeof m.c
                    // In the above example when we start with checking if typeof m.c symbol is accessible,
                    // we are going to see if c can be accessed in scope directly.
                    // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
                    // It is accessible if the parent m is accessible because then m.c can be accessed through qualification
                    meaningToLook = getQualifiedLeftMeaning(meaning);
                    symbol = getParentOfSymbol(symbol);
                }
                // This could be a symbol that is not exported in the external module
                // or it could be a symbol from different external module that is not aliased and hence cannot be named
                var symbolExternalModule = ts.forEach(initialSymbol.declarations, getExternalModuleContainer);
                if (symbolExternalModule) {
                    var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
                    if (symbolExternalModule !== enclosingExternalModule) {
                        // name from different external module that is not visible
                        return {
                            accessibility: 2 /* CannotBeNamed */,
                            errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                            errorModuleName: symbolToString(symbolExternalModule)
                        };
                    }
                }
                // Just a local name that is not accessible
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                };
            }
            return { accessibility: 0 /* Accessible */ };
            function getExternalModuleContainer(declaration) {
                var node = ts.findAncestor(declaration, hasExternalModuleSymbol);
                return node && getSymbolOfNode(node);
            }
        }
        function hasExternalModuleSymbol(declaration) {
            return ts.isAmbientModule(declaration) || (declaration.kind === 265 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) {
            var aliasesToMakeVisible;
            if (ts.forEach(symbol.declarations, function (declaration) { return !getIsDeclarationVisible(declaration); })) {
                return undefined;
            }
            return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible };
            function getIsDeclarationVisible(declaration) {
                if (!isDeclarationVisible(declaration)) {
                    // Mark the unexported alias as visible if its parent is visible
                    // because these kind of aliases can be used to name types in declaration file
                    var anyImportSyntax = getAnyImportSyntax(declaration);
                    if (anyImportSyntax &&
                        !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export
                        isDeclarationVisible(anyImportSyntax.parent)) {
                        // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types,
                        // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time
                        // since we will do the emitting later in trackSymbol.
                        if (shouldComputeAliasToMakeVisible) {
                            getNodeLinks(declaration).isVisible = true;
                            aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, anyImportSyntax);
                        }
                        return true;
                    }
                    // Declaration is not visible
                    return false;
                }
                return true;
            }
        }
        function isEntityNameVisible(entityName, enclosingDeclaration) {
            // get symbol of the first identifier of the entityName
            var meaning;
            if (entityName.parent.kind === 162 /* TypeQuery */ || ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
                // Typeof value
                meaning = 107455 /* Value */ | 1048576 /* ExportValue */;
            }
            else if (entityName.kind === 143 /* QualifiedName */ || entityName.kind === 179 /* PropertyAccessExpression */ ||
                entityName.parent.kind === 237 /* ImportEqualsDeclaration */) {
                // Left identifier from type reference or TypeAlias
                // Entity name of the import declaration
                meaning = 1920 /* Namespace */;
            }
            else {
                // Type Reference or TypeAlias entity = Identifier
                meaning = 793064 /* Type */;
            }
            var firstIdentifier = getFirstIdentifier(entityName);
            var symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
            // Verify if the symbol is accessible
            return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || {
                accessibility: 1 /* NotAccessible */,
                errorSymbolName: ts.getTextOfNode(firstIdentifier),
                errorNode: firstIdentifier
            };
        }
        function writeKeyword(writer, kind) {
            writer.writeKeyword(ts.tokenToString(kind));
        }
        function writePunctuation(writer, kind) {
            writer.writePunctuation(ts.tokenToString(kind));
        }
        function writeSpace(writer) {
            writer.writeSpace(" ");
        }
        function symbolToString(symbol, enclosingDeclaration, meaning) {
            return ts.usingSingleLineStringWriter(function (writer) {
                getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
            });
        }
        function signatureToString(signature, enclosingDeclaration, flags, kind) {
            return ts.usingSingleLineStringWriter(function (writer) {
                getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind);
            });
        }
        function typeToString(type, enclosingDeclaration, flags) {
            var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName);
            ts.Debug.assert(typeNode !== undefined, "should always get typenode");
            var options = { removeComments: true };
            var writer = ts.createTextWriter("");
            var printer = ts.createPrinter(options);
            var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
            printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer);
            var result = writer.getText();
            var maxLength = compilerOptions.noErrorTruncation || flags & 8 /* NoTruncation */ ? undefined : 100;
            if (maxLength && result.length >= maxLength) {
                return result.substr(0, maxLength - "...".length) + "...";
            }
            return result;
            function toNodeBuilderFlags(flags) {
                var result = ts.NodeBuilderFlags.None;
                if (!flags) {
                    return result;
                }
                if (flags & 8 /* NoTruncation */) {
                    result |= ts.NodeBuilderFlags.NoTruncation;
                }
                if (flags & 256 /* UseFullyQualifiedType */) {
                    result |= ts.NodeBuilderFlags.UseFullyQualifiedType;
                }
                if (flags & 4096 /* SuppressAnyReturnType */) {
                    result |= ts.NodeBuilderFlags.SuppressAnyReturnType;
                }
                if (flags & 1 /* WriteArrayAsGenericType */) {
                    result |= ts.NodeBuilderFlags.WriteArrayAsGenericType;
                }
                if (flags & 64 /* WriteTypeArgumentsOfSignature */) {
                    result |= ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature;
                }
                return result;
            }
        }
        function createNodeBuilder() {
            return {
                typeToTypeNode: function (type, enclosingDeclaration, flags) {
                    var context = createNodeBuilderContext(enclosingDeclaration, flags);
                    var resultingNode = typeToTypeNodeHelper(type, context);
                    var result = context.encounteredError ? undefined : resultingNode;
                    return result;
                },
                indexInfoToIndexSignatureDeclaration: function (indexInfo, kind, enclosingDeclaration, flags) {
                    var context = createNodeBuilderContext(enclosingDeclaration, flags);
                    var resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context);
                    var result = context.encounteredError ? undefined : resultingNode;
                    return result;
                },
                signatureToSignatureDeclaration: function (signature, kind, enclosingDeclaration, flags) {
                    var context = createNodeBuilderContext(enclosingDeclaration, flags);
                    var resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context);
                    var result = context.encounteredError ? undefined : resultingNode;
                    return result;
                }
            };
            function createNodeBuilderContext(enclosingDeclaration, flags) {
                return {
                    enclosingDeclaration: enclosingDeclaration,
                    flags: flags,
                    encounteredError: false,
                    symbolStack: undefined
                };
            }
            function typeToTypeNodeHelper(type, context) {
                var inTypeAlias = context.flags & ts.NodeBuilderFlags.InTypeAlias;
                context.flags &= ~ts.NodeBuilderFlags.InTypeAlias;
                if (!type) {
                    context.encounteredError = true;
                    return undefined;
                }
                if (type.flags & 1 /* Any */) {
                    return ts.createKeywordTypeNode(119 /* AnyKeyword */);
                }
                if (type.flags & 2 /* String */) {
                    return ts.createKeywordTypeNode(136 /* StringKeyword */);
                }
                if (type.flags & 4 /* Number */) {
                    return ts.createKeywordTypeNode(133 /* NumberKeyword */);
                }
                if (type.flags & 8 /* Boolean */) {
                    return ts.createKeywordTypeNode(122 /* BooleanKeyword */);
                }
                if (type.flags & 256 /* EnumLiteral */ && !(type.flags & 65536 /* Union */)) {
                    var parentSymbol = getParentOfSymbol(type.symbol);
                    var parentName = symbolToName(parentSymbol, context, 793064 /* Type */, /*expectsIdentifier*/ false);
                    var enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : ts.createQualifiedName(parentName, getNameOfSymbol(type.symbol, context));
                    return ts.createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
                }
                if (type.flags & 272 /* EnumLike */) {
                    var name = symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false);
                    return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined);
                }
                if (type.flags & (32 /* StringLiteral */)) {
                    return ts.createLiteralTypeNode(ts.setEmitFlags(ts.createLiteral(type.value), 16777216 /* NoAsciiEscaping */));
                }
                if (type.flags & (64 /* NumberLiteral */)) {
                    return ts.createLiteralTypeNode((ts.createLiteral(type.value)));
                }
                if (type.flags & 128 /* BooleanLiteral */) {
                    return type.intrinsicName === "true" ? ts.createTrue() : ts.createFalse();
                }
                if (type.flags & 1024 /* Void */) {
                    return ts.createKeywordTypeNode(105 /* VoidKeyword */);
                }
                if (type.flags & 2048 /* Undefined */) {
                    return ts.createKeywordTypeNode(139 /* UndefinedKeyword */);
                }
                if (type.flags & 4096 /* Null */) {
                    return ts.createKeywordTypeNode(95 /* NullKeyword */);
                }
                if (type.flags & 8192 /* Never */) {
                    return ts.createKeywordTypeNode(130 /* NeverKeyword */);
                }
                if (type.flags & 512 /* ESSymbol */) {
                    return ts.createKeywordTypeNode(137 /* SymbolKeyword */);
                }
                if (type.flags & 16777216 /* NonPrimitive */) {
                    return ts.createKeywordTypeNode(134 /* ObjectKeyword */);
                }
                if (type.flags & 16384 /* TypeParameter */ && type.isThisType) {
                    if (context.flags & ts.NodeBuilderFlags.InObjectTypeLiteral) {
                        if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowThisInObjectLiteral)) {
                            context.encounteredError = true;
                        }
                    }
                    return ts.createThis();
                }
                var objectFlags = getObjectFlags(type);
                if (objectFlags & 4 /* Reference */) {
                    ts.Debug.assert(!!(type.flags & 32768 /* Object */));
                    return typeReferenceToTypeNode(type);
                }
                if (type.flags & 16384 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) {
                    var name = type.symbol ? symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("?");
                    // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
                    return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined);
                }
                if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) {
                    var name = symbolToTypeReferenceName(type.aliasSymbol);
                    var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
                    return ts.createTypeReferenceNode(name, typeArgumentNodes);
                }
                if (type.flags & (65536 /* Union */ | 131072 /* Intersection */)) {
                    var types = type.flags & 65536 /* Union */ ? formatUnionTypes(type.types) : type.types;
                    var typeNodes = mapToTypeNodes(types, context);
                    if (typeNodes && typeNodes.length > 0) {
                        var unionOrIntersectionTypeNode = ts.createUnionOrIntersectionTypeNode(type.flags & 65536 /* Union */ ? 166 /* UnionType */ : 167 /* IntersectionType */, typeNodes);
                        return unionOrIntersectionTypeNode;
                    }
                    else {
                        if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowEmptyUnionOrIntersection)) {
                            context.encounteredError = true;
                        }
                        return undefined;
                    }
                }
                if (objectFlags & (16 /* Anonymous */ | 32 /* Mapped */)) {
                    ts.Debug.assert(!!(type.flags & 32768 /* Object */));
                    // The type is an object literal type.
                    return createAnonymousTypeNode(type);
                }
                if (type.flags & 262144 /* Index */) {
                    var indexedType = type.type;
                    var indexTypeNode = typeToTypeNodeHelper(indexedType, context);
                    return ts.createTypeOperatorNode(indexTypeNode);
                }
                if (type.flags & 524288 /* IndexedAccess */) {
                    var objectTypeNode = typeToTypeNodeHelper(type.objectType, context);
                    var indexTypeNode = typeToTypeNodeHelper(type.indexType, context);
                    return ts.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
                }
                ts.Debug.fail("Should be unreachable.");
                function createMappedTypeNodeFromType(type) {
                    ts.Debug.assert(!!(type.flags & 32768 /* Object */));
                    var readonlyToken = type.declaration && type.declaration.readonlyToken ? ts.createToken(131 /* ReadonlyKeyword */) : undefined;
                    var questionToken = type.declaration && type.declaration.questionToken ? ts.createToken(55 /* QuestionToken */) : undefined;
                    var typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context);
                    var templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
                    var mappedTypeNode = ts.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
                    return ts.setEmitFlags(mappedTypeNode, 1 /* SingleLine */);
                }
                function createAnonymousTypeNode(type) {
                    var symbol = type.symbol;
                    if (symbol) {
                        // Always use 'typeof T' for type of class, enum, and module objects
                        if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) ||
                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */) ||
                            shouldWriteTypeOfFunctionSymbol()) {
                            return createTypeQueryNodeFromSymbol(symbol, 107455 /* Value */);
                        }
                        else if (ts.contains(context.symbolStack, symbol)) {
                            // If type is an anonymous type literal in a type alias declaration, use type alias name
                            var typeAlias = getTypeAliasForTypeLiteral(type);
                            if (typeAlias) {
                                // The specified symbol flags need to be reinterpreted as type flags
                                var entityName = symbolToName(typeAlias, context, 793064 /* Type */, /*expectsIdentifier*/ false);
                                return ts.createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
                            }
                            else {
                                return ts.createKeywordTypeNode(119 /* AnyKeyword */);
                            }
                        }
                        else {
                            // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
                            // of types allows us to catch circular references to instantiations of the same anonymous type
                            if (!context.symbolStack) {
                                context.symbolStack = [];
                            }
                            context.symbolStack.push(symbol);
                            var result = createTypeNodeFromObjectType(type);
                            context.symbolStack.pop();
                            return result;
                        }
                    }
                    else {
                        // Anonymous types without a symbol are never circular.
                        return createTypeNodeFromObjectType(type);
                    }
                    function shouldWriteTypeOfFunctionSymbol() {
                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
                            (symbol.parent || // is exported function symbol
                                ts.forEach(symbol.declarations, function (declaration) {
                                    return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */;
                                }));
                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                            // typeof is allowed only for static/non local functions
                            return ts.contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively
                        }
                    }
                }
                function createTypeNodeFromObjectType(type) {
                    if (isGenericMappedType(type)) {
                        return createMappedTypeNodeFromType(type);
                    }
                    var resolved = resolveStructuredTypeMembers(type);
                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                            return ts.setEmitFlags(ts.createTypeLiteralNode(/*members*/ undefined), 1 /* SingleLine */);
                        }
                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                            var signature = resolved.callSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 160 /* FunctionType */, context);
                            return signatureNode;
                        }
                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                            var signature = resolved.constructSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 161 /* ConstructorType */, context);
                            return signatureNode;
                        }
                    }
                    var savedFlags = context.flags;
                    context.flags |= ts.NodeBuilderFlags.InObjectTypeLiteral;
                    var members = createTypeNodesFromResolvedType(resolved);
                    context.flags = savedFlags;
                    var typeLiteralNode = ts.createTypeLiteralNode(members);
                    return ts.setEmitFlags(typeLiteralNode, 1 /* SingleLine */);
                }
                function createTypeQueryNodeFromSymbol(symbol, symbolFlags) {
                    var entityName = symbolToName(symbol, context, symbolFlags, /*expectsIdentifier*/ false);
                    return ts.createTypeQueryNode(entityName);
                }
                function symbolToTypeReferenceName(symbol) {
                    // Unnamed function expressions and arrow functions have reserved names that we don't want to display
                    var entityName = symbol.flags & 32 /* Class */ || !isReservedMemberName(symbol.escapedName) ? symbolToName(symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("");
                    return entityName;
                }
                function typeReferenceToTypeNode(type) {
                    var typeArguments = type.typeArguments || ts.emptyArray;
                    if (type.target === globalArrayType) {
                        if (context.flags & ts.NodeBuilderFlags.WriteArrayAsGenericType) {
                            var typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
                            return ts.createTypeReferenceNode("Array", [typeArgumentNode]);
                        }
                        var elementType = typeToTypeNodeHelper(typeArguments[0], context);
                        return ts.createArrayTypeNode(elementType);
                    }
                    else if (type.target.objectFlags & 8 /* Tuple */) {
                        if (typeArguments.length > 0) {
                            var tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, getTypeReferenceArity(type)), context);
                            if (tupleConstituentNodes && tupleConstituentNodes.length > 0) {
                                return ts.createTupleTypeNode(tupleConstituentNodes);
                            }
                        }
                        if (context.encounteredError || (context.flags & ts.NodeBuilderFlags.AllowEmptyTuple)) {
                            return ts.createTupleTypeNode([]);
                        }
                        context.encounteredError = true;
                        return undefined;
                    }
                    else {
                        var outerTypeParameters = type.target.outerTypeParameters;
                        var i = 0;
                        var qualifiedName = void 0;
                        if (outerTypeParameters) {
                            var length_1 = outerTypeParameters.length;
                            while (i < length_1) {
                                // Find group of type arguments for type parameters with the same declaring container.
                                var start = i;
                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
                                do {
                                    i++;
                                } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
                                // When type parameters are their own type arguments for the whole group (i.e. we have
                                // the default outer type arguments), we don't show the group.
                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
                                    var typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context);
                                    var typeArgumentNodes_1 = typeArgumentSlice && ts.createNodeArray(typeArgumentSlice);
                                    var namePart = symbolToTypeReferenceName(parent);
                                    (namePart.kind === 71 /* Identifier */ ? namePart : namePart.right).typeArguments = typeArgumentNodes_1;
                                    if (qualifiedName) {
                                        ts.Debug.assert(!qualifiedName.right);
                                        qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, namePart);
                                        qualifiedName = ts.createQualifiedName(qualifiedName, /*right*/ undefined);
                                    }
                                    else {
                                        qualifiedName = ts.createQualifiedName(namePart, /*right*/ undefined);
                                    }
                                }
                            }
                        }
                        var entityName = undefined;
                        var nameIdentifier = symbolToTypeReferenceName(type.symbol);
                        if (qualifiedName) {
                            ts.Debug.assert(!qualifiedName.right);
                            qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, nameIdentifier);
                            entityName = qualifiedName;
                        }
                        else {
                            entityName = nameIdentifier;
                        }
                        var typeArgumentNodes = void 0;
                        if (typeArguments.length > 0) {
                            var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
                            typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
                        }
                        if (typeArgumentNodes) {
                            var lastIdentifier = entityName.kind === 71 /* Identifier */ ? entityName : entityName.right;
                            lastIdentifier.typeArguments = undefined;
                        }
                        return ts.createTypeReferenceNode(entityName, typeArgumentNodes);
                    }
                }
                function addToQualifiedNameMissingRightIdentifier(left, right) {
                    ts.Debug.assert(left.right === undefined);
                    if (right.kind === 71 /* Identifier */) {
                        left.right = right;
                        return left;
                    }
                    var rightPart = right;
                    while (rightPart.left.kind !== 71 /* Identifier */) {
                        rightPart = rightPart.left;
                    }
                    left.right = rightPart.left;
                    rightPart.left = left;
                    return right;
                }
                function createTypeNodesFromResolvedType(resolvedType) {
                    var typeElements = [];
                    for (var _i = 0, _a = resolvedType.callSignatures; _i < _a.length; _i++) {
                        var signature = _a[_i];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 155 /* CallSignature */, context));
                    }
                    for (var _b = 0, _c = resolvedType.constructSignatures; _b < _c.length; _b++) {
                        var signature = _c[_b];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 156 /* ConstructSignature */, context));
                    }
                    if (resolvedType.stringIndexInfo) {
                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, 0 /* String */, context));
                    }
                    if (resolvedType.numberIndexInfo) {
                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, 1 /* Number */, context));
                    }
                    var properties = resolvedType.properties;
                    if (!properties) {
                        return typeElements;
                    }
                    for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) {
                        var propertySymbol = properties_1[_d];
                        var propertyType = getTypeOfSymbol(propertySymbol);
                        var saveEnclosingDeclaration = context.enclosingDeclaration;
                        context.enclosingDeclaration = undefined;
                        var propertyName = symbolToName(propertySymbol, context, 107455 /* Value */, /*expectsIdentifier*/ true);
                        context.enclosingDeclaration = saveEnclosingDeclaration;
                        var optionalToken = propertySymbol.flags & 16777216 /* Optional */ ? ts.createToken(55 /* QuestionToken */) : undefined;
                        if (propertySymbol.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(propertyType).length) {
                            var signatures = getSignaturesOfType(propertyType, 0 /* Call */);
                            for (var _e = 0, signatures_1 = signatures; _e < signatures_1.length; _e++) {
                                var signature = signatures_1[_e];
                                var methodDeclaration = signatureToSignatureDeclarationHelper(signature, 150 /* MethodSignature */, context);
                                methodDeclaration.name = propertyName;
                                methodDeclaration.questionToken = optionalToken;
                                typeElements.push(methodDeclaration);
                            }
                        }
                        else {
                            var propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : ts.createKeywordTypeNode(119 /* AnyKeyword */);
                            var modifiers = isReadonlySymbol(propertySymbol) ? [ts.createToken(131 /* ReadonlyKeyword */)] : undefined;
                            var propertySignature = ts.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode, 
                            /*initializer*/ undefined);
                            typeElements.push(propertySignature);
                        }
                    }
                    return typeElements.length ? typeElements : undefined;
                }
            }
            function mapToTypeNodes(types, context) {
                if (ts.some(types)) {
                    var result = [];
                    for (var i = 0; i < types.length; ++i) {
                        var type = types[i];
                        var typeNode = typeToTypeNodeHelper(type, context);
                        if (typeNode) {
                            result.push(typeNode);
                        }
                    }
                    return result;
                }
            }
            function indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context) {
                var name = ts.getNameFromIndexInfo(indexInfo) || "x";
                var indexerTypeNode = ts.createKeywordTypeNode(kind === 0 /* String */ ? 136 /* StringKeyword */ : 133 /* NumberKeyword */);
                var indexingParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, name, 
                /*questionToken*/ undefined, indexerTypeNode, 
                /*initializer*/ undefined);
                var typeNode = typeToTypeNodeHelper(indexInfo.type, context);
                return ts.createIndexSignature(
                /*decorators*/ undefined, indexInfo.isReadonly ? [ts.createToken(131 /* ReadonlyKeyword */)] : undefined, [indexingParameter], typeNode);
            }
            function signatureToSignatureDeclarationHelper(signature, kind, context) {
                var typeParameters = signature.typeParameters && signature.typeParameters.map(function (parameter) { return typeParameterToDeclaration(parameter, context); });
                var parameters = signature.parameters.map(function (parameter) { return symbolToParameterDeclaration(parameter, context); });
                if (signature.thisParameter) {
                    var thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
                    parameters.unshift(thisParameter);
                }
                var returnTypeNode;
                if (signature.typePredicate) {
                    var typePredicate = signature.typePredicate;
                    var parameterName = typePredicate.kind === 1 /* Identifier */ ?
                        ts.setEmitFlags(ts.createIdentifier(typePredicate.parameterName), 16777216 /* NoAsciiEscaping */) :
                        ts.createThisTypeNode();
                    var typeNode = typeToTypeNodeHelper(typePredicate.type, context);
                    returnTypeNode = ts.createTypePredicateNode(parameterName, typeNode);
                }
                else {
                    var returnType = getReturnTypeOfSignature(signature);
                    returnTypeNode = returnType && typeToTypeNodeHelper(returnType, context);
                }
                if (context.flags & ts.NodeBuilderFlags.SuppressAnyReturnType) {
                    if (returnTypeNode && returnTypeNode.kind === 119 /* AnyKeyword */) {
                        returnTypeNode = undefined;
                    }
                }
                else if (!returnTypeNode) {
                    returnTypeNode = ts.createKeywordTypeNode(119 /* AnyKeyword */);
                }
                return ts.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode);
            }
            function typeParameterToDeclaration(type, context) {
                var name = symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ true);
                var constraint = getConstraintFromTypeParameter(type);
                var constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
                var defaultParameter = getDefaultFromTypeParameter(type);
                var defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
                return ts.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
            }
            function symbolToParameterDeclaration(parameterSymbol, context) {
                var parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 146 /* Parameter */);
                if (isTransientSymbol(parameterSymbol) && parameterSymbol.isRestParameter) {
                    // special-case synthetic rest parameters in JS files
                    return ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, parameterSymbol.isRestParameter ? ts.createToken(24 /* DotDotDotToken */) : undefined, "args", 
                    /*questionToken*/ undefined, typeToTypeNodeHelper(anyArrayType, context), 
                    /*initializer*/ undefined);
                }
                var modifiers = parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(ts.getSynthesizedClone);
                var dotDotDotToken = ts.isRestParameter(parameterDeclaration) ? ts.createToken(24 /* DotDotDotToken */) : undefined;
                var name = parameterDeclaration.name ?
                    parameterDeclaration.name.kind === 71 /* Identifier */ ?
                        ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name), 16777216 /* NoAsciiEscaping */) :
                        cloneBindingName(parameterDeclaration.name) :
                    ts.symbolName(parameterSymbol);
                var questionToken = isOptionalParameter(parameterDeclaration) ? ts.createToken(55 /* QuestionToken */) : undefined;
                var parameterType = getTypeOfSymbol(parameterSymbol);
                if (isRequiredInitializedParameter(parameterDeclaration)) {
                    parameterType = getNullableType(parameterType, 2048 /* Undefined */);
                }
                var parameterTypeNode = typeToTypeNodeHelper(parameterType, context);
                var parameterNode = ts.createParameter(
                /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, 
                /*initializer*/ undefined);
                return parameterNode;
                function cloneBindingName(node) {
                    return elideInitializerAndSetEmitFlags(node);
                    function elideInitializerAndSetEmitFlags(node) {
                        var visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags);
                        var clone = ts.nodeIsSynthesized(visited) ? visited : ts.getSynthesizedClone(visited);
                        if (clone.kind === 176 /* BindingElement */) {
                            clone.initializer = undefined;
                        }
                        return ts.setEmitFlags(clone, 1 /* SingleLine */ | 16777216 /* NoAsciiEscaping */);
                    }
                }
            }
            function symbolToName(symbol, context, meaning, expectsIdentifier) {
                // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
                var chain;
                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
                if (!isTypeParameter && (context.enclosingDeclaration || context.flags & ts.NodeBuilderFlags.UseFullyQualifiedType)) {
                    chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true);
                    ts.Debug.assert(chain && chain.length > 0);
                }
                else {
                    chain = [symbol];
                }
                if (expectsIdentifier && chain.length !== 1
                    && !context.encounteredError
                    && !(context.flags & ts.NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) {
                    context.encounteredError = true;
                }
                return createEntityNameFromSymbolChain(chain, chain.length - 1);
                function createEntityNameFromSymbolChain(chain, index) {
                    ts.Debug.assert(chain && 0 <= index && index < chain.length);
                    var symbol = chain[index];
                    var typeParameterNodes;
                    if (context.flags & ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) {
                        var parentSymbol = chain[index - 1];
                        var typeParameters = void 0;
                        if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                            typeParameters = getTypeParametersOfClassOrInterface(parentSymbol);
                        }
                        else {
                            var targetSymbol = getTargetSymbol(parentSymbol);
                            if (targetSymbol.flags & (32 /* Class */ | 64 /* Interface */ | 524288 /* TypeAlias */)) {
                                typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                            }
                        }
                        typeParameterNodes = mapToTypeNodes(typeParameters, context);
                    }
                    var symbolName = getNameOfSymbol(symbol, context);
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    return index > 0 ? ts.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
                }
                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
                function getSymbolChain(symbol, meaning, endOfChain) {
                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false);
                    var parentSymbol;
                    if (!accessibleSymbolChain ||
                        needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
                        // Go up and add our parent.
                        var parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol);
                        if (parent) {
                            var parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
                            if (parentChain) {
                                parentSymbol = parent;
                                accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]);
                            }
                        }
                    }
                    if (accessibleSymbolChain) {
                        return accessibleSymbolChain;
                    }
                    if (
                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
                    endOfChain ||
                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
                        !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) &&
                            // If a parent symbol is an anonymous type, don't write it.
                            !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
                        return [symbol];
                    }
                }
            }
        }
        function typePredicateToString(typePredicate, enclosingDeclaration, flags) {
            return ts.usingSingleLineStringWriter(function (writer) {
                getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags);
            });
        }
        function formatUnionTypes(types) {
            var result = [];
            var flags = 0;
            for (var i = 0; i < types.length; i++) {
                var t = types[i];
                flags |= t.flags;
                if (!(t.flags & 6144 /* Nullable */)) {
                    if (t.flags & (128 /* BooleanLiteral */ | 256 /* EnumLiteral */)) {
                        var baseType = t.flags & 128 /* BooleanLiteral */ ? booleanType : getBaseTypeOfEnumLiteralType(t);
                        if (baseType.flags & 65536 /* Union */) {
                            var count = baseType.types.length;
                            if (i + count <= types.length && types[i + count - 1] === baseType.types[count - 1]) {
                                result.push(baseType);
                                i += count - 1;
                                continue;
                            }
                        }
                    }
                    result.push(t);
                }
            }
            if (flags & 4096 /* Null */)
                result.push(nullType);
            if (flags & 2048 /* Undefined */)
                result.push(undefinedType);
            return result || types;
        }
        function visibilityToString(flags) {
            if (flags === 8 /* Private */) {
                return "private";
            }
            if (flags === 16 /* Protected */) {
                return "protected";
            }
            return "public";
        }
        function getTypeAliasForTypeLiteral(type) {
            if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) {
                var node = ts.findAncestor(type.symbol.declarations[0].parent, function (n) { return n.kind !== 168 /* ParenthesizedType */; });
                if (node.kind === 231 /* TypeAliasDeclaration */) {
                    return getSymbolOfNode(node);
                }
            }
            return undefined;
        }
        function isTopLevelInExternalModuleAugmentation(node) {
            return node && node.parent &&
                node.parent.kind === 234 /* ModuleBlock */ &&
                ts.isExternalModuleAugmentation(node.parent.parent);
        }
        function literalTypeToString(type) {
            return type.flags & 32 /* StringLiteral */ ? '"' + ts.escapeString(type.value) + '"' : "" + type.value;
        }
        function getNameOfSymbol(symbol, context) {
            if (symbol.declarations && symbol.declarations.length) {
                var declaration = symbol.declarations[0];
                var name = ts.getNameOfDeclaration(declaration);
                if (name) {
                    return ts.declarationNameToString(name);
                }
                if (declaration.parent && declaration.parent.kind === 226 /* VariableDeclaration */) {
                    return ts.declarationNameToString(declaration.parent.name);
                }
                if (context && !context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowAnonymousIdentifier)) {
                    context.encounteredError = true;
                }
                switch (declaration.kind) {
                    case 199 /* ClassExpression */:
                        return "(Anonymous class)";
                    case 186 /* FunctionExpression */:
                    case 187 /* ArrowFunction */:
                        return "(Anonymous function)";
                }
            }
            if (symbol.syntheticLiteralTypeOrigin) {
                var stringValue = symbol.syntheticLiteralTypeOrigin.value;
                if (!ts.isIdentifierText(stringValue, compilerOptions.target)) {
                    return "\"" + ts.escapeString(stringValue, 34 /* doubleQuote */) + "\"";
                }
            }
            return ts.symbolName(symbol);
        }
        function getSymbolDisplayBuilder() {
            /**
             * Writes only the name of the symbol out to the writer. Uses the original source text
             * for the name of the symbol if it is available to match how the user wrote the name.
             */
            function appendSymbolNameOnly(symbol, writer) {
                writer.writeSymbol(getNameOfSymbol(symbol), symbol);
            }
            /**
             * Writes a property access or element access with the name of the symbol out to the writer.
             * Uses the original source text for the name of the symbol if it is available to match how the user wrote the name,
             * ensuring that any names written with literals use element accesses.
             */
            function appendPropertyOrElementAccessForSymbol(symbol, writer) {
                var symbolName = getNameOfSymbol(symbol);
                var firstChar = symbolName.charCodeAt(0);
                var needsElementAccess = !ts.isIdentifierStart(firstChar, languageVersion);
                if (needsElementAccess) {
                    writePunctuation(writer, 21 /* OpenBracketToken */);
                    if (ts.isSingleOrDoubleQuote(firstChar)) {
                        writer.writeStringLiteral(symbolName);
                    }
                    else {
                        writer.writeSymbol(symbolName, symbol);
                    }
                    writePunctuation(writer, 22 /* CloseBracketToken */);
                }
                else {
                    writePunctuation(writer, 23 /* DotToken */);
                    writer.writeSymbol(symbolName, symbol);
                }
            }
            /**
             * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope
             * Meaning needs to be specified if the enclosing declaration is given
             */
            function buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags, typeFlags) {
                var parentSymbol;
                function appendParentTypeArgumentsAndSymbolName(symbol) {
                    if (parentSymbol) {
                        // Write type arguments of instantiated class/interface here
                        if (flags & 1 /* WriteTypeParametersOrArguments */) {
                            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                                var params = getTypeParametersOfClassOrInterface(parentSymbol.flags & 2097152 /* Alias */ ? resolveAlias(parentSymbol) : parentSymbol);
                                buildDisplayForTypeArgumentsAndDelimiters(params, symbol.mapper, writer, enclosingDeclaration);
                            }
                            else {
                                buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration);
                            }
                        }
                        appendPropertyOrElementAccessForSymbol(symbol, writer);
                    }
                    else {
                        appendSymbolNameOnly(symbol, writer);
                    }
                    parentSymbol = symbol;
                }
                // Let the writer know we just wrote out a symbol.  The declaration emitter writer uses
                // this to determine if an import it has previously seen (and not written out) needs
                // to be written to the file once the walk of the tree is complete.
                //
                // NOTE(cyrusn): This approach feels somewhat unfortunate.  A simple pass over the tree
                // up front (for example, during checking) could determine if we need to emit the imports
                // and we could then access that data during declaration emit.
                writer.trackSymbol(symbol, enclosingDeclaration, meaning);
                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
                function walkSymbol(symbol, meaning, endOfChain) {
                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, !!(flags & 2 /* UseOnlyExternalAliasing */));
                    if (!accessibleSymbolChain ||
                        needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
                        // Go up and add our parent.
                        var parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol);
                        if (parent) {
                            walkSymbol(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
                        }
                    }
                    if (accessibleSymbolChain) {
                        for (var _i = 0, accessibleSymbolChain_1 = accessibleSymbolChain; _i < accessibleSymbolChain_1.length; _i++) {
                            var accessibleSymbol = accessibleSymbolChain_1[_i];
                            appendParentTypeArgumentsAndSymbolName(accessibleSymbol);
                        }
                    }
                    else if (
                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
                    endOfChain ||
                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
                        !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) &&
                            // If a parent symbol is an anonymous type, don't write it.
                            !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
                        appendParentTypeArgumentsAndSymbolName(symbol);
                    }
                }
                // Get qualified name if the symbol is not a type parameter
                // and there is an enclosing declaration or we specifically
                // asked for it
                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
                var typeFormatFlag = 256 /* UseFullyQualifiedType */ & typeFlags;
                if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) {
                    walkSymbol(symbol, meaning, /*endOfChain*/ true);
                }
                else {
                    appendParentTypeArgumentsAndSymbolName(symbol);
                }
            }
            function buildTypeDisplay(type, writer, enclosingDeclaration, globalFlags, symbolStack) {
                var globalFlagsToPass = globalFlags & (32 /* WriteOwnNameForAnyLike */ | 16384 /* WriteClassExpressionAsTypeLiteral */);
                var inObjectTypeLiteral = false;
                return writeType(type, globalFlags);
                function writeType(type, flags) {
                    var nextFlags = flags & ~1024 /* InTypeAlias */;
                    // Write undefined/null type as any
                    if (type.flags & 16793231 /* Intrinsic */) {
                        // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving
                        writer.writeKeyword(!(globalFlags & 32 /* WriteOwnNameForAnyLike */) && isTypeAny(type)
                            ? "any"
                            : type.intrinsicName);
                    }
                    else if (type.flags & 16384 /* TypeParameter */ && type.isThisType) {
                        if (inObjectTypeLiteral) {
                            writer.reportInaccessibleThisError();
                        }
                        writer.writeKeyword("this");
                    }
                    else if (getObjectFlags(type) & 4 /* Reference */) {
                        writeTypeReference(type, nextFlags);
                    }
                    else if (type.flags & 256 /* EnumLiteral */ && !(type.flags & 65536 /* Union */)) {
                        var parent = getParentOfSymbol(type.symbol);
                        buildSymbolDisplay(parent, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags);
                        // In a literal enum type with a single member E { A }, E and E.A denote the
                        // same type. We always display this type simply as E.
                        if (getDeclaredTypeOfSymbol(parent) !== type) {
                            writePunctuation(writer, 23 /* DotToken */);
                            appendSymbolNameOnly(type.symbol, writer);
                        }
                    }
                    else if (getObjectFlags(type) & 3 /* ClassOrInterface */ || type.flags & (272 /* EnumLike */ | 16384 /* TypeParameter */)) {
                        // The specified symbol flags need to be reinterpreted as type flags
                        buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags);
                    }
                    else if (!(flags & 1024 /* InTypeAlias */) && type.aliasSymbol &&
                        ((flags & 65536 /* UseAliasDefinedOutsideCurrentScope */) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) {
                        var typeArguments = type.aliasTypeArguments;
                        writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags);
                    }
                    else if (type.flags & 196608 /* UnionOrIntersection */) {
                        writeUnionOrIntersectionType(type, nextFlags);
                    }
                    else if (getObjectFlags(type) & (16 /* Anonymous */ | 32 /* Mapped */)) {
                        writeAnonymousType(type, nextFlags);
                    }
                    else if (type.flags & 96 /* StringOrNumberLiteral */) {
                        writer.writeStringLiteral(literalTypeToString(type));
                    }
                    else if (type.flags & 262144 /* Index */) {
                        if (flags & 128 /* InElementType */) {
                            writePunctuation(writer, 19 /* OpenParenToken */);
                        }
                        writer.writeKeyword("keyof");
                        writeSpace(writer);
                        writeType(type.type, 128 /* InElementType */);
                        if (flags & 128 /* InElementType */) {
                            writePunctuation(writer, 20 /* CloseParenToken */);
                        }
                    }
                    else if (type.flags & 524288 /* IndexedAccess */) {
                        writeType(type.objectType, 128 /* InElementType */);
                        writePunctuation(writer, 21 /* OpenBracketToken */);
                        writeType(type.indexType, 0 /* None */);
                        writePunctuation(writer, 22 /* CloseBracketToken */);
                    }
                    else {
                        // Should never get here
                        // { ... }
                        writePunctuation(writer, 17 /* OpenBraceToken */);
                        writeSpace(writer);
                        writePunctuation(writer, 24 /* DotDotDotToken */);
                        writeSpace(writer);
                        writePunctuation(writer, 18 /* CloseBraceToken */);
                    }
                }
                function writeTypeList(types, delimiter) {
                    for (var i = 0; i < types.length; i++) {
                        if (i > 0) {
                            if (delimiter !== 26 /* CommaToken */) {
                                writeSpace(writer);
                            }
                            writePunctuation(writer, delimiter);
                            writeSpace(writer);
                        }
                        writeType(types[i], delimiter === 26 /* CommaToken */ ? 0 /* None */ : 128 /* InElementType */);
                    }
                }
                function writeSymbolTypeReference(symbol, typeArguments, pos, end, flags) {
                    // Unnamed function expressions and arrow functions have reserved names that we don't want to display
                    if (symbol.flags & 32 /* Class */ || !isReservedMemberName(symbol.escapedName)) {
                        buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, flags);
                    }
                    if (pos < end) {
                        writePunctuation(writer, 27 /* LessThanToken */);
                        writeType(typeArguments[pos], 512 /* InFirstTypeArgument */);
                        pos++;
                        while (pos < end) {
                            writePunctuation(writer, 26 /* CommaToken */);
                            writeSpace(writer);
                            writeType(typeArguments[pos], 0 /* None */);
                            pos++;
                        }
                        writePunctuation(writer, 29 /* GreaterThanToken */);
                    }
                }
                function writeTypeReference(type, flags) {
                    var typeArguments = type.typeArguments || ts.emptyArray;
                    if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) {
                        writeType(typeArguments[0], 128 /* InElementType */ | 32768 /* InArrayType */);
                        writePunctuation(writer, 21 /* OpenBracketToken */);
                        writePunctuation(writer, 22 /* CloseBracketToken */);
                    }
                    else if (type.target.objectFlags & 8 /* Tuple */) {
                        writePunctuation(writer, 21 /* OpenBracketToken */);
                        writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), 26 /* CommaToken */);
                        writePunctuation(writer, 22 /* CloseBracketToken */);
                    }
                    else if (flags & 16384 /* WriteClassExpressionAsTypeLiteral */ &&
                        type.symbol.valueDeclaration &&
                        type.symbol.valueDeclaration.kind === 199 /* ClassExpression */) {
                        writeAnonymousType(type, flags);
                    }
                    else {
                        // Write the type reference in the format f<A>.g<B>.C<X, Y> where A and B are type arguments
                        // for outer type parameters, and f and g are the respective declaring containers of those
                        // type parameters.
                        var outerTypeParameters = type.target.outerTypeParameters;
                        var i = 0;
                        if (outerTypeParameters) {
                            var length_2 = outerTypeParameters.length;
                            while (i < length_2) {
                                // Find group of type arguments for type parameters with the same declaring container.
                                var start = i;
                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
                                do {
                                    i++;
                                } while (i < length_2 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
                                // When type parameters are their own type arguments for the whole group (i.e. we have
                                // the default outer type arguments), we don't show the group.
                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
                                    writeSymbolTypeReference(parent, typeArguments, start, i, flags);
                                    writePunctuation(writer, 23 /* DotToken */);
                                }
                            }
                        }
                        var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
                        writeSymbolTypeReference(type.symbol, typeArguments, i, typeParameterCount, flags);
                    }
                }
                function writeUnionOrIntersectionType(type, flags) {
                    if (flags & 128 /* InElementType */) {
                        writePunctuation(writer, 19 /* OpenParenToken */);
                    }
                    if (type.flags & 65536 /* Union */) {
                        writeTypeList(formatUnionTypes(type.types), 49 /* BarToken */);
                    }
                    else {
                        writeTypeList(type.types, 48 /* AmpersandToken */);
                    }
                    if (flags & 128 /* InElementType */) {
                        writePunctuation(writer, 20 /* CloseParenToken */);
                    }
                }
                function writeAnonymousType(type, flags) {
                    var symbol = type.symbol;
                    if (symbol) {
                        // Always use 'typeof T' for type of class, enum, and module objects
                        if (symbol.flags & 32 /* Class */ &&
                            !getBaseTypeVariableOfClass(symbol) &&
                            !(symbol.valueDeclaration.kind === 199 /* ClassExpression */ && flags & 16384 /* WriteClassExpressionAsTypeLiteral */) ||
                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */)) {
                            writeTypeOfSymbol(type, flags);
                        }
                        else if (shouldWriteTypeOfFunctionSymbol()) {
                            writeTypeOfSymbol(type, flags);
                        }
                        else if (ts.contains(symbolStack, symbol)) {
                            // If type is an anonymous type literal in a type alias declaration, use type alias name
                            var typeAlias = getTypeAliasForTypeLiteral(type);
                            if (typeAlias) {
                                // The specified symbol flags need to be reinterpreted as type flags
                                buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, flags);
                            }
                            else {
                                // Recursive usage, use any
                                writeKeyword(writer, 119 /* AnyKeyword */);
                            }
                        }
                        else {
                            // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
                            // of types allows us to catch circular references to instantiations of the same anonymous type
                            // However, in case of class expressions, we want to write both the static side and the instance side.
                            // We skip adding the static side so that the instance side has a chance to be written
                            // before checking for circular references.
                            if (!symbolStack) {
                                symbolStack = [];
                            }
                            var isConstructorObject = type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */;
                            if (isConstructorObject) {
                                writeLiteralType(type, flags);
                            }
                            else {
                                symbolStack.push(symbol);
                                writeLiteralType(type, flags);
                                symbolStack.pop();
                            }
                        }
                    }
                    else {
                        // Anonymous types with no symbol are never circular
                        writeLiteralType(type, flags);
                    }
                    function shouldWriteTypeOfFunctionSymbol() {
                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
                            (symbol.parent || // is exported function symbol
                                ts.some(symbol.declarations, function (declaration) {
                                    return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */;
                                }));
                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                            // typeof is allowed only for static/non local functions
                            return !!(flags & 4 /* UseTypeOfFunction */) || // use typeof if format flags specify it
                                ts.contains(symbolStack, symbol); // it is type of the symbol uses itself recursively
                        }
                    }
                }
                function writeTypeOfSymbol(type, typeFormatFlags) {
                    if (typeFormatFlags & 32768 /* InArrayType */) {
                        writePunctuation(writer, 19 /* OpenParenToken */);
                    }
                    writeKeyword(writer, 103 /* TypeOfKeyword */);
                    writeSpace(writer);
                    buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 107455 /* Value */, 0 /* None */, typeFormatFlags);
                    if (typeFormatFlags & 32768 /* InArrayType */) {
                        writePunctuation(writer, 20 /* CloseParenToken */);
                    }
                }
                function writePropertyWithModifiers(prop) {
                    if (isReadonlySymbol(prop)) {
                        writeKeyword(writer, 131 /* ReadonlyKeyword */);
                        writeSpace(writer);
                    }
                    buildSymbolDisplay(prop, writer);
                    if (prop.flags & 16777216 /* Optional */) {
                        writePunctuation(writer, 55 /* QuestionToken */);
                    }
                }
                function shouldAddParenthesisAroundFunctionType(callSignature, flags) {
                    if (flags & 128 /* InElementType */) {
                        return true;
                    }
                    else if (flags & 512 /* InFirstTypeArgument */) {
                        // Add parenthesis around function type for the first type argument to avoid ambiguity
                        var typeParameters = callSignature.target && (flags & 64 /* WriteTypeArgumentsOfSignature */) ?
                            callSignature.target.typeParameters : callSignature.typeParameters;
                        return typeParameters && typeParameters.length !== 0;
                    }
                    return false;
                }
                function writeLiteralType(type, flags) {
                    if (isGenericMappedType(type)) {
                        writeMappedType(type);
                        return;
                    }
                    var resolved = resolveStructuredTypeMembers(type);
                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                            writePunctuation(writer, 17 /* OpenBraceToken */);
                            writePunctuation(writer, 18 /* CloseBraceToken */);
                            return;
                        }
                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                            var parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags);
                            if (parenthesizeSignature) {
                                writePunctuation(writer, 19 /* OpenParenToken */);
                            }
                            buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 16 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack);
                            if (parenthesizeSignature) {
                                writePunctuation(writer, 20 /* CloseParenToken */);
                            }
                            return;
                        }
                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                            if (flags & 128 /* InElementType */) {
                                writePunctuation(writer, 19 /* OpenParenToken */);
                            }
                            writeKeyword(writer, 94 /* NewKeyword */);
                            writeSpace(writer);
                            buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 16 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack);
                            if (flags & 128 /* InElementType */) {
                                writePunctuation(writer, 20 /* CloseParenToken */);
                            }
                            return;
                        }
                    }
                    var saveInObjectTypeLiteral = inObjectTypeLiteral;
                    inObjectTypeLiteral = true;
                    writePunctuation(writer, 17 /* OpenBraceToken */);
                    writer.writeLine();
                    writer.increaseIndent();
                    writeObjectLiteralType(resolved);
                    writer.decreaseIndent();
                    writePunctuation(writer, 18 /* CloseBraceToken */);
                    inObjectTypeLiteral = saveInObjectTypeLiteral;
                }
                function writeObjectLiteralType(resolved) {
                    for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
                        var signature = _a[_i];
                        buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack);
                        writePunctuation(writer, 25 /* SemicolonToken */);
                        writer.writeLine();
                    }
                    for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
                        var signature = _c[_b];
                        buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, 1 /* Construct */, symbolStack);
                        writePunctuation(writer, 25 /* SemicolonToken */);
                        writer.writeLine();
                    }
                    buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, 0 /* String */, enclosingDeclaration, globalFlags, symbolStack);
                    buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, 1 /* Number */, enclosingDeclaration, globalFlags, symbolStack);
                    for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
                        var p = _e[_d];
                        if (globalFlags & 16384 /* WriteClassExpressionAsTypeLiteral */) {
                            if (p.flags & 4194304 /* Prototype */) {
                                continue;
                            }
                            if (ts.getDeclarationModifierFlagsFromSymbol(p) & (8 /* Private */ | 16 /* Protected */)) {
                                writer.reportPrivateInBaseOfClassExpression(ts.symbolName(p));
                            }
                        }
                        var t = getTypeOfSymbol(p);
                        if (p.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(t).length) {
                            var signatures = getSignaturesOfType(t, 0 /* Call */);
                            for (var _f = 0, signatures_2 = signatures; _f < signatures_2.length; _f++) {
                                var signature = signatures_2[_f];
                                writePropertyWithModifiers(p);
                                buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack);
                                writePunctuation(writer, 25 /* SemicolonToken */);
                                writer.writeLine();
                            }
                        }
                        else {
                            writePropertyWithModifiers(p);
                            writePunctuation(writer, 56 /* ColonToken */);
                            writeSpace(writer);
                            writeType(t, globalFlags & 16384 /* WriteClassExpressionAsTypeLiteral */);
                            writePunctuation(writer, 25 /* SemicolonToken */);
                            writer.writeLine();
                        }
                    }
                }
                function writeMappedType(type) {
                    writePunctuation(writer, 17 /* OpenBraceToken */);
                    writer.writeLine();
                    writer.increaseIndent();
                    if (type.declaration.readonlyToken) {
                        writeKeyword(writer, 131 /* ReadonlyKeyword */);
                        writeSpace(writer);
                    }
                    writePunctuation(writer, 21 /* OpenBracketToken */);
                    appendSymbolNameOnly(getTypeParameterFromMappedType(type).symbol, writer);
                    writeSpace(writer);
                    writeKeyword(writer, 92 /* InKeyword */);
                    writeSpace(writer);
                    writeType(getConstraintTypeFromMappedType(type), 0 /* None */);
                    writePunctuation(writer, 22 /* CloseBracketToken */);
                    if (type.declaration.questionToken) {
                        writePunctuation(writer, 55 /* QuestionToken */);
                    }
                    writePunctuation(writer, 56 /* ColonToken */);
                    writeSpace(writer);
                    writeType(getTemplateTypeFromMappedType(type), 0 /* None */);
                    writePunctuation(writer, 25 /* SemicolonToken */);
                    writer.writeLine();
                    writer.decreaseIndent();
                    writePunctuation(writer, 18 /* CloseBraceToken */);
                }
            }
            function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration, flags) {
                var targetSymbol = getTargetSymbol(symbol);
                if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) {
                    buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaration, flags);
                }
            }
            function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, symbolStack) {
                appendSymbolNameOnly(tp.symbol, writer);
                var constraint = getConstraintOfTypeParameter(tp);
                if (constraint) {
                    writeSpace(writer);
                    writeKeyword(writer, 85 /* ExtendsKeyword */);
                    writeSpace(writer);
                    buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack);
                }
                var defaultType = getDefaultFromTypeParameter(tp);
                if (defaultType) {
                    writeSpace(writer);
                    writePunctuation(writer, 58 /* EqualsToken */);
                    writeSpace(writer);
                    buildTypeDisplay(defaultType, writer, enclosingDeclaration, flags, symbolStack);
                }
            }
            function buildParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack) {
                var parameterNode = p.valueDeclaration;
                if (parameterNode ? ts.isRestParameter(parameterNode) : isTransientSymbol(p) && p.isRestParameter) {
                    writePunctuation(writer, 24 /* DotDotDotToken */);
                }
                if (parameterNode && ts.isBindingPattern(parameterNode.name)) {
                    buildBindingPatternDisplay(parameterNode.name, writer, enclosingDeclaration, flags, symbolStack);
                }
                else {
                    appendSymbolNameOnly(p, writer);
                }
                if (parameterNode && isOptionalParameter(parameterNode)) {
                    writePunctuation(writer, 55 /* QuestionToken */);
                }
                writePunctuation(writer, 56 /* ColonToken */);
                writeSpace(writer);
                var type = getTypeOfSymbol(p);
                if (parameterNode && isRequiredInitializedParameter(parameterNode)) {
                    type = getNullableType(type, 2048 /* Undefined */);
                }
                buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
            }
            function buildBindingPatternDisplay(bindingPattern, writer, enclosingDeclaration, flags, symbolStack) {
                // We have to explicitly emit square bracket and bracket because these tokens are not stored inside the node.
                if (bindingPattern.kind === 174 /* ObjectBindingPattern */) {
                    writePunctuation(writer, 17 /* OpenBraceToken */);
                    buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); });
                    writePunctuation(writer, 18 /* CloseBraceToken */);
                }
                else if (bindingPattern.kind === 175 /* ArrayBindingPattern */) {
                    writePunctuation(writer, 21 /* OpenBracketToken */);
                    var elements = bindingPattern.elements;
                    buildDisplayForCommaSeparatedList(elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); });
                    if (elements && elements.hasTrailingComma) {
                        writePunctuation(writer, 26 /* CommaToken */);
                    }
                    writePunctuation(writer, 22 /* CloseBracketToken */);
                }
            }
            function buildBindingElementDisplay(bindingElement, writer, enclosingDeclaration, flags, symbolStack) {
                if (ts.isOmittedExpression(bindingElement)) {
                    return;
                }
                ts.Debug.assert(bindingElement.kind === 176 /* BindingElement */);
                if (bindingElement.propertyName) {
                    writer.writeProperty(ts.getTextOfNode(bindingElement.propertyName));
                    writePunctuation(writer, 56 /* ColonToken */);
                    writeSpace(writer);
                }
                if (ts.isBindingPattern(bindingElement.name)) {
                    buildBindingPatternDisplay(bindingElement.name, writer, enclosingDeclaration, flags, symbolStack);
                }
                else {
                    if (bindingElement.dotDotDotToken) {
                        writePunctuation(writer, 24 /* DotDotDotToken */);
                    }
                    appendSymbolNameOnly(bindingElement.symbol, writer);
                }
            }
            function buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, flags, symbolStack) {
                if (typeParameters && typeParameters.length) {
                    writePunctuation(writer, 27 /* LessThanToken */);
                    buildDisplayForCommaSeparatedList(typeParameters, writer, function (p) { return buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack); });
                    writePunctuation(writer, 29 /* GreaterThanToken */);
                }
            }
            function buildDisplayForCommaSeparatedList(list, writer, action) {
                for (var i = 0; i < list.length; i++) {
                    if (i > 0) {
                        writePunctuation(writer, 26 /* CommaToken */);
                        writeSpace(writer);
                    }
                    action(list[i]);
                }
            }
            function buildDisplayForTypeArgumentsAndDelimiters(typeParameters, mapper, writer, enclosingDeclaration) {
                if (typeParameters && typeParameters.length) {
                    writePunctuation(writer, 27 /* LessThanToken */);
                    var flags = 512 /* InFirstTypeArgument */;
                    for (var i = 0; i < typeParameters.length; i++) {
                        if (i > 0) {
                            writePunctuation(writer, 26 /* CommaToken */);
                            writeSpace(writer);
                            flags = 0 /* None */;
                        }
                        buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags);
                    }
                    writePunctuation(writer, 29 /* GreaterThanToken */);
                }
            }
            function buildDisplayForParametersAndDelimiters(thisParameter, parameters, writer, enclosingDeclaration, flags, symbolStack) {
                writePunctuation(writer, 19 /* OpenParenToken */);
                if (thisParameter) {
                    buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack);
                }
                for (var i = 0; i < parameters.length; i++) {
                    if (i > 0 || thisParameter) {
                        writePunctuation(writer, 26 /* CommaToken */);
                        writeSpace(writer);
                    }
                    buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack);
                }
                writePunctuation(writer, 20 /* CloseParenToken */);
            }
            function buildTypePredicateDisplay(predicate, writer, enclosingDeclaration, flags, symbolStack) {
                if (ts.isIdentifierTypePredicate(predicate)) {
                    writer.writeParameter(predicate.parameterName);
                }
                else {
                    writeKeyword(writer, 99 /* ThisKeyword */);
                }
                writeSpace(writer);
                writeKeyword(writer, 126 /* IsKeyword */);
                writeSpace(writer);
                buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack);
            }
            function buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack) {
                var returnType = getReturnTypeOfSignature(signature);
                if (flags & 4096 /* SuppressAnyReturnType */ && isTypeAny(returnType)) {
                    return;
                }
                if (flags & 16 /* WriteArrowStyleSignature */) {
                    writeSpace(writer);
                    writePunctuation(writer, 36 /* EqualsGreaterThanToken */);
                }
                else {
                    writePunctuation(writer, 56 /* ColonToken */);
                }
                writeSpace(writer);
                if (signature.typePredicate) {
                    buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack);
                }
                else {
                    buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
                }
            }
            function buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind, symbolStack) {
                if (kind === 1 /* Construct */) {
                    writeKeyword(writer, 94 /* NewKeyword */);
                    writeSpace(writer);
                }
                if (signature.target && (flags & 64 /* WriteTypeArgumentsOfSignature */)) {
                    // Instantiated signature, write type arguments instead
                    // This is achieved by passing in the mapper separately
                    buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration);
                }
                else {
                    buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack);
                }
                buildDisplayForParametersAndDelimiters(signature.thisParameter, signature.parameters, writer, enclosingDeclaration, flags, symbolStack);
                buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack);
            }
            function buildIndexSignatureDisplay(info, writer, kind, enclosingDeclaration, globalFlags, symbolStack) {
                if (info) {
                    if (info.isReadonly) {
                        writeKeyword(writer, 131 /* ReadonlyKeyword */);
                        writeSpace(writer);
                    }
                    writePunctuation(writer, 21 /* OpenBracketToken */);
                    writer.writeParameter(info.declaration ? ts.declarationNameToString(info.declaration.parameters[0].name) : "x");
                    writePunctuation(writer, 56 /* ColonToken */);
                    writeSpace(writer);
                    switch (kind) {
                        case 1 /* Number */:
                            writeKeyword(writer, 133 /* NumberKeyword */);
                            break;
                        case 0 /* String */:
                            writeKeyword(writer, 136 /* StringKeyword */);
                            break;
                    }
                    writePunctuation(writer, 22 /* CloseBracketToken */);
                    writePunctuation(writer, 56 /* ColonToken */);
                    writeSpace(writer);
                    buildTypeDisplay(info.type, writer, enclosingDeclaration, globalFlags, symbolStack);
                    writePunctuation(writer, 25 /* SemicolonToken */);
                    writer.writeLine();
                }
            }
            return _displayBuilder || (_displayBuilder = {
                buildSymbolDisplay: buildSymbolDisplay,
                buildTypeDisplay: buildTypeDisplay,
                buildTypeParameterDisplay: buildTypeParameterDisplay,
                buildTypePredicateDisplay: buildTypePredicateDisplay,
                buildParameterDisplay: buildParameterDisplay,
                buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
                buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
                buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,
                buildSignatureDisplay: buildSignatureDisplay,
                buildIndexSignatureDisplay: buildIndexSignatureDisplay,
                buildReturnTypeDisplay: buildReturnTypeDisplay
            });
        }
        function isDeclarationVisible(node) {
            if (node) {
                var links = getNodeLinks(node);
                if (links.isVisible === undefined) {
                    links.isVisible = !!determineIfDeclarationIsVisible();
                }
                return links.isVisible;
            }
            return false;
            function determineIfDeclarationIsVisible() {
                switch (node.kind) {
                    case 176 /* BindingElement */:
                        return isDeclarationVisible(node.parent.parent);
                    case 226 /* VariableDeclaration */:
                        if (ts.isBindingPattern(node.name) &&
                            !node.name.elements.length) {
                            // If the binding pattern is empty, this variable declaration is not visible
                            return false;
                        }
                    // falls through
                    case 233 /* ModuleDeclaration */:
                    case 229 /* ClassDeclaration */:
                    case 230 /* InterfaceDeclaration */:
                    case 231 /* TypeAliasDeclaration */:
                    case 228 /* FunctionDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 237 /* ImportEqualsDeclaration */:
                        // external module augmentation is always visible
                        if (ts.isExternalModuleAugmentation(node)) {
                            return true;
                        }
                        var parent = getDeclarationContainer(node);
                        // If the node is not exported or it is not ambient module element (except import declaration)
                        if (!(ts.getCombinedModifierFlags(node) & 1 /* Export */) &&
                            !(node.kind !== 237 /* ImportEqualsDeclaration */ && parent.kind !== 265 /* SourceFile */ && ts.isInAmbientContext(parent))) {
                            return isGlobalSourceFile(parent);
                        }
                        // Exported members/ambient module elements (exception import declaration) are visible if parent is visible
                        return isDeclarationVisible(parent);
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                        if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) {
                            // Private/protected properties/methods are not visible
                            return false;
                        }
                    // Public properties/methods are visible if its parents are visible, so:
                    // falls through
                    case 152 /* Constructor */:
                    case 156 /* ConstructSignature */:
                    case 155 /* CallSignature */:
                    case 157 /* IndexSignature */:
                    case 146 /* Parameter */:
                    case 234 /* ModuleBlock */:
                    case 160 /* FunctionType */:
                    case 161 /* ConstructorType */:
                    case 163 /* TypeLiteral */:
                    case 159 /* TypeReference */:
                    case 164 /* ArrayType */:
                    case 165 /* TupleType */:
                    case 166 /* UnionType */:
                    case 167 /* IntersectionType */:
                    case 168 /* ParenthesizedType */:
                        return isDeclarationVisible(node.parent);
                    // Default binding, import specifier and namespace import is visible
                    // only on demand so by default it is not visible
                    case 239 /* ImportClause */:
                    case 240 /* NamespaceImport */:
                    case 242 /* ImportSpecifier */:
                        return false;
                    // Type parameters are always visible
                    case 145 /* TypeParameter */:
                    // Source file and namespace export are always visible
                    case 265 /* SourceFile */:
                    case 236 /* NamespaceExportDeclaration */:
                        return true;
                    // Export assignments do not create name bindings outside the module
                    case 243 /* ExportAssignment */:
                        return false;
                    default:
                        return false;
                }
            }
        }
        function collectLinkedAliases(node) {
            var exportSymbol;
            if (node.parent && node.parent.kind === 243 /* ExportAssignment */) {
                exportSymbol = resolveName(node.parent, node.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, ts.Diagnostics.Cannot_find_name_0, node, /*isUse*/ false);
            }
            else if (node.parent.kind === 246 /* ExportSpecifier */) {
                exportSymbol = getTargetOfExportSpecifier(node.parent, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
            }
            var result = [];
            if (exportSymbol) {
                buildVisibleNodeList(exportSymbol.declarations);
            }
            return result;
            function buildVisibleNodeList(declarations) {
                ts.forEach(declarations, function (declaration) {
                    getNodeLinks(declaration).isVisible = true;
                    var resultNode = getAnyImportSyntax(declaration) || declaration;
                    ts.pushIfUnique(result, resultNode);
                    if (ts.isInternalModuleImportEqualsDeclaration(declaration)) {
                        // Add the referenced top container visible
                        var internalModuleReference = declaration.moduleReference;
                        var firstIdentifier = getFirstIdentifier(internalModuleReference);
                        var importSymbol = resolveName(declaration, firstIdentifier.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, undefined, undefined, /*isUse*/ false);
                        if (importSymbol) {
                            buildVisibleNodeList(importSymbol.declarations);
                        }
                    }
                });
            }
        }
        /**
         * Push an entry on the type resolution stack. If an entry with the given target and the given property name
         * is already on the stack, and no entries in between already have a type, then a circularity has occurred.
         * In this case, the result values of the existing entry and all entries pushed after it are changed to false,
         * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
         * In order to see if the same query has already been done before, the target object and the propertyName both
         * must match the one passed in.
         *
         * @param target The symbol, type, or signature whose type is being queried
         * @param propertyName The property name that should be used to query the target for its type
         */
        function pushTypeResolution(target, propertyName) {
            var resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
            if (resolutionCycleStartIndex >= 0) {
                // A cycle was found
                var length_3 = resolutionTargets.length;
                for (var i = resolutionCycleStartIndex; i < length_3; i++) {
                    resolutionResults[i] = false;
                }
                return false;
            }
            resolutionTargets.push(target);
            resolutionResults.push(/*items*/ true);
            resolutionPropertyNames.push(propertyName);
            return true;
        }
        function findResolutionCycleStartIndex(target, propertyName) {
            for (var i = resolutionTargets.length - 1; i >= 0; i--) {
                if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
                    return -1;
                }
                if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
                    return i;
                }
            }
            return -1;
        }
        function hasType(target, propertyName) {
            if (propertyName === 0 /* Type */) {
                return getSymbolLinks(target).type;
            }
            if (propertyName === 2 /* DeclaredType */) {
                return getSymbolLinks(target).declaredType;
            }
            if (propertyName === 1 /* ResolvedBaseConstructorType */) {
                return target.resolvedBaseConstructorType;
            }
            if (propertyName === 3 /* ResolvedReturnType */) {
                return target.resolvedReturnType;
            }
            ts.Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
        }
        // Pop an entry from the type resolution stack and return its associated result value. The result value will
        // be true if no circularities were detected, or false if a circularity was found.
        function popTypeResolution() {
            resolutionTargets.pop();
            resolutionPropertyNames.pop();
            return resolutionResults.pop();
        }
        function getDeclarationContainer(node) {
            node = ts.findAncestor(ts.getRootDeclaration(node), function (node) {
                switch (node.kind) {
                    case 226 /* VariableDeclaration */:
                    case 227 /* VariableDeclarationList */:
                    case 242 /* ImportSpecifier */:
                    case 241 /* NamedImports */:
                    case 240 /* NamespaceImport */:
                    case 239 /* ImportClause */:
                        return false;
                    default:
                        return true;
                }
            });
            return node && node.parent;
        }
        function getTypeOfPrototypeProperty(prototype) {
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype',
            // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
            // It is an error to explicitly declare a static property member with the name 'prototype'.
            var classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype));
            return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType;
        }
        // Return the type of the given property in the given type, or undefined if no such property exists
        function getTypeOfPropertyOfType(type, name) {
            var prop = getPropertyOfType(type, name);
            return prop ? getTypeOfSymbol(prop) : undefined;
        }
        function isTypeAny(type) {
            return type && (type.flags & 1 /* Any */) !== 0;
        }
        // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
        // assigned by contextual typing.
        function getTypeForBindingElementParent(node) {
            var symbol = getSymbolOfNode(node);
            return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
        }
        function isComputedNonLiteralName(name) {
            return name.kind === 144 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteral(name.expression);
        }
        function getRestType(source, properties, symbol) {
            source = filterType(source, function (t) { return !(t.flags & 6144 /* Nullable */); });
            if (source.flags & 8192 /* Never */) {
                return emptyObjectType;
            }
            if (source.flags & 65536 /* Union */) {
                return mapType(source, function (t) { return getRestType(t, properties, symbol); });
            }
            var members = ts.createSymbolTable();
            var names = ts.createUnderscoreEscapedMap();
            for (var _i = 0, properties_2 = properties; _i < properties_2.length; _i++) {
                var name = properties_2[_i];
                names.set(ts.getTextOfPropertyName(name), true);
            }
            for (var _a = 0, _b = getPropertiesOfType(source); _a < _b.length; _a++) {
                var prop = _b[_a];
                var inNamesToRemove = names.has(prop.escapedName);
                var isPrivate = ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */);
                var isSetOnlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
                if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) {
                    members.set(prop.escapedName, prop);
                }
            }
            var stringIndexInfo = getIndexInfoOfType(source, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(source, 1 /* Number */);
            return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
        }
        /** Return the inferred type for a binding element */
        function getTypeForBindingElement(declaration) {
            var pattern = declaration.parent;
            var parentType = getTypeForBindingElementParent(pattern.parent);
            // If parent has the unknown (error) type, then so does this binding element
            if (parentType === unknownType) {
                return unknownType;
            }
            // If no type was specified or inferred for parent,
            // infer from the initializer of the binding element if one is present.
            // Otherwise, go with the undefined type of the parent.
            if (!parentType) {
                return declaration.initializer ? checkDeclarationInitializer(declaration) : parentType;
            }
            if (isTypeAny(parentType)) {
                return parentType;
            }
            var type;
            if (pattern.kind === 174 /* ObjectBindingPattern */) {
                if (declaration.dotDotDotToken) {
                    if (!isValidSpreadType(parentType)) {
                        error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types);
                        return unknownType;
                    }
                    var literalMembers = [];
                    for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!element.dotDotDotToken) {
                            literalMembers.push(element.propertyName || element.name);
                        }
                    }
                    type = getRestType(parentType, literalMembers, declaration.symbol);
                }
                else {
                    // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                    var name = declaration.propertyName || declaration.name;
                    if (isComputedNonLiteralName(name)) {
                        // computed properties with non-literal names are treated as 'any'
                        return anyType;
                    }
                    // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
                    // or otherwise the type of the string index signature.
                    var text = ts.getTextOfPropertyName(name);
                    var declaredType = getTypeOfPropertyOfType(parentType, text);
                    type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
                        isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
                        getIndexTypeOfType(parentType, 0 /* String */);
                    if (!type) {
                        error(name, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name));
                        return unknownType;
                    }
                }
            }
            else {
                // This elementType will be used if the specific property corresponding to this index is not
                // present (aka the tuple element property). This call also checks that the parentType is in
                // fact an iterable or array (depending on target language).
                var elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false, /*allowAsyncIterables*/ false);
                if (declaration.dotDotDotToken) {
                    // Rest element has an array type with the same element type as the parent type
                    type = createArrayType(elementType);
                }
                else {
                    // Use specific property type when parent is a tuple or numeric index type when parent is an array
                    var propName = "" + ts.indexOf(pattern.elements, declaration);
                    type = isTupleLikeType(parentType)
                        ? getTypeOfPropertyOfType(parentType, propName)
                        : elementType;
                    if (!type) {
                        if (isTupleType(parentType)) {
                            error(declaration, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length);
                        }
                        else {
                            error(declaration, ts.Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName);
                        }
                        return unknownType;
                    }
                }
            }
            // In strict null checking mode, if a default value of a non-undefined type is specified, remove
            // undefined from the final type.
            if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkExpressionCached(declaration.initializer)) & 2048 /* Undefined */)) {
                type = getTypeWithFacts(type, 131072 /* NEUndefined */);
            }
            return declaration.initializer ?
                getUnionType([type, checkExpressionCached(declaration.initializer)], /*subtypeReduction*/ true) :
                type;
        }
        function getTypeForDeclarationFromJSDocComment(declaration) {
            var jsdocType = ts.getJSDocType(declaration);
            if (jsdocType) {
                return getTypeFromTypeNode(jsdocType);
            }
            return undefined;
        }
        function isNullOrUndefined(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 95 /* NullKeyword */ || expr.kind === 71 /* Identifier */ && getResolvedSymbol(expr) === undefinedSymbol;
        }
        function isEmptyArrayLiteral(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 177 /* ArrayLiteralExpression */ && expr.elements.length === 0;
        }
        function addOptionality(type, optional) {
            return strictNullChecks && optional ? getNullableType(type, 2048 /* Undefined */) : type;
        }
        // Return the inferred type for a variable, parameter, or property declaration
        function getTypeForVariableLikeDeclaration(declaration, includeOptionality) {
            // A variable declared in a for..in statement is of type string, or of type keyof T when the
            // right hand expression is of a type parameter type.
            if (declaration.parent.parent.kind === 215 /* ForInStatement */) {
                var indexType = getIndexType(checkNonNullExpression(declaration.parent.parent.expression));
                return indexType.flags & (16384 /* TypeParameter */ | 262144 /* Index */) ? indexType : stringType;
            }
            if (declaration.parent.parent.kind === 216 /* ForOfStatement */) {
                // checkRightHandSideOfForOf will return undefined if the for-of expression type was
                // missing properties/signatures required to get its iteratedType (like
                // [Symbol.iterator] or next). This may be because we accessed properties from anyType,
                // or it may have led to an error inside getElementTypeOfIterable.
                var forOfStatement = declaration.parent.parent;
                return checkRightHandSideOfForOf(forOfStatement.expression, forOfStatement.awaitModifier) || anyType;
            }
            if (ts.isBindingPattern(declaration.parent)) {
                return getTypeForBindingElement(declaration);
            }
            // Use type from type annotation if one is present
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                var declaredType = getTypeFromTypeNode(typeNode);
                return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
            }
            if ((noImplicitAny || ts.isInJavaScriptFile(declaration)) &&
                declaration.kind === 226 /* VariableDeclaration */ && !ts.isBindingPattern(declaration.name) &&
                !(ts.getCombinedModifierFlags(declaration) & 1 /* Export */) && !ts.isInAmbientContext(declaration)) {
                // If --noImplicitAny is on or the declaration is in a Javascript file,
                // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
                // initializer or a 'null' or 'undefined' initializer.
                if (!(ts.getCombinedNodeFlags(declaration) & 2 /* Const */) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) {
                    return autoType;
                }
                // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array
                // literal initializer.
                if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) {
                    return autoArrayType;
                }
            }
            if (declaration.kind === 146 /* Parameter */) {
                var func = declaration.parent;
                // For a parameter of a set accessor, use the type of the get accessor if one is present
                if (func.kind === 154 /* SetAccessor */ && !ts.hasDynamicName(func)) {
                    var getter = ts.getDeclarationOfKind(declaration.parent.symbol, 153 /* GetAccessor */);
                    if (getter) {
                        var getterSignature = getSignatureFromDeclaration(getter);
                        var thisParameter = getAccessorThisParameter(func);
                        if (thisParameter && declaration === thisParameter) {
                            // Use the type from the *getter*
                            ts.Debug.assert(!thisParameter.type);
                            return getTypeOfSymbol(getterSignature.thisParameter);
                        }
                        return getReturnTypeOfSignature(getterSignature);
                    }
                }
                // Use contextual parameter type if one is available
                var type = void 0;
                if (declaration.symbol.escapedName === "this") {
                    type = getContextualThisParameterType(func);
                }
                else {
                    type = getContextuallyTypedParameterType(declaration);
                }
                if (type) {
                    return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
                }
            }
            // Use the type of the initializer expression if one is present
            if (declaration.initializer) {
                var type = checkDeclarationInitializer(declaration);
                return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
            }
            if (ts.isJsxAttribute(declaration)) {
                // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true.
                // I.e <Elem attr /> is sugar for <Elem attr={true} />
                return trueType;
            }
            // If it is a short-hand property assignment, use the type of the identifier
            if (declaration.kind === 262 /* ShorthandPropertyAssignment */) {
                return checkIdentifier(declaration.name);
            }
            // If the declaration specifies a binding pattern, use the type implied by the binding pattern
            if (ts.isBindingPattern(declaration.name)) {
                return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
            }
            // No type specified and nothing can be inferred
            return undefined;
        }
        function getWidenedTypeFromJSSpecialPropertyDeclarations(symbol) {
            var types = [];
            var definedInConstructor = false;
            var definedInMethod = false;
            var jsDocType;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                var expression = declaration.kind === 194 /* BinaryExpression */ ? declaration :
                    declaration.kind === 179 /* PropertyAccessExpression */ ? ts.getAncestor(declaration, 194 /* BinaryExpression */) :
                        undefined;
                if (!expression) {
                    return unknownType;
                }
                if (ts.isPropertyAccessExpression(expression.left) && expression.left.expression.kind === 99 /* ThisKeyword */) {
                    if (ts.getThisContainer(expression, /*includeArrowFunctions*/ false).kind === 152 /* Constructor */) {
                        definedInConstructor = true;
                    }
                    else {
                        definedInMethod = true;
                    }
                }
                // If there is a JSDoc type, use it
                var type_1 = getTypeForDeclarationFromJSDocComment(expression.parent);
                if (type_1) {
                    var declarationType = getWidenedType(type_1);
                    if (!jsDocType) {
                        jsDocType = declarationType;
                    }
                    else if (jsDocType !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(jsDocType, declarationType)) {
                        var name = ts.getNameOfDeclaration(declaration);
                        error(name, ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, ts.declarationNameToString(name), typeToString(jsDocType), typeToString(declarationType));
                    }
                }
                else if (!jsDocType) {
                    // If we don't have an explicit JSDoc type, get the type from the expression.
                    types.push(getWidenedLiteralType(checkExpressionCached(expression.right)));
                }
            }
            var type = jsDocType || getUnionType(types, /*subtypeReduction*/ true);
            return getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
        }
        // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
        // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
        // pattern. Otherwise, it is the type any.
        function getTypeFromBindingElement(element, includePatternInType, reportErrors) {
            if (element.initializer) {
                return checkDeclarationInitializer(element);
            }
            if (ts.isBindingPattern(element.name)) {
                return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors);
            }
            if (reportErrors && noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
                reportImplicitAnyError(element, anyType);
            }
            return anyType;
        }
        // Return the type implied by an object binding pattern
        function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var hasComputedProperties = false;
            ts.forEach(pattern.elements, function (e) {
                var name = e.propertyName || e.name;
                if (isComputedNonLiteralName(name)) {
                    // do not include computed properties in the implied type
                    hasComputedProperties = true;
                    return;
                }
                if (e.dotDotDotToken) {
                    stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    return;
                }
                var text = ts.getTextOfPropertyName(name);
                var flags = 4 /* Property */ | (e.initializer ? 16777216 /* Optional */ : 0);
                var symbol = createSymbol(flags, text);
                symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
                symbol.bindingElement = e;
                members.set(symbol.escapedName, symbol);
            });
            var result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
            if (includePatternInType) {
                result.pattern = pattern;
            }
            if (hasComputedProperties) {
                result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
            }
            return result;
        }
        // Return the type implied by an array binding pattern
        function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) {
            var elements = pattern.elements;
            var lastElement = ts.lastOrUndefined(elements);
            if (elements.length === 0 || (!ts.isOmittedExpression(lastElement) && lastElement.dotDotDotToken)) {
                return languageVersion >= 2 /* ES2015 */ ? createIterableType(anyType) : anyArrayType;
            }
            // If the pattern has at least one element, and no rest element, then it should imply a tuple type.
            var elementTypes = ts.map(elements, function (e) { return ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); });
            var result = createTupleType(elementTypes);
            if (includePatternInType) {
                result = cloneTypeReference(result);
                result.pattern = pattern;
            }
            return result;
        }
        // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
        // and without regard to its context (i.e. without regard any type annotation or initializer associated with the
        // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any]
        // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is
        // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
        // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
        // the parameter.
        function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) {
            return pattern.kind === 174 /* ObjectBindingPattern */
                ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
                : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
        }
        // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
        // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it
        // is a bit more involved. For example:
        //
        //   var [x, s = ""] = [1, "one"];
        //
        // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the
        // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the
        // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string.
        function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) {
            var type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
            if (type) {
                if (reportErrors) {
                    reportErrorsFromWidening(declaration, type);
                }
                // During a normal type check we'll never get to here with a property assignment (the check of the containing
                // object literal uses a different path). We exclude widening only so that language services and type verification
                // tools see the actual type.
                if (declaration.kind === 261 /* PropertyAssignment */) {
                    return type;
                }
                return getWidenedType(type);
            }
            // Rest parameters default to type any[], other parameters default to type any
            type = declaration.dotDotDotToken ? anyArrayType : anyType;
            // Report implicit any errors unless this is a private property within an ambient declaration
            if (reportErrors && noImplicitAny) {
                if (!declarationBelongsToPrivateAmbientMember(declaration)) {
                    reportImplicitAnyError(declaration, type);
                }
            }
            return type;
        }
        function declarationBelongsToPrivateAmbientMember(declaration) {
            var root = ts.getRootDeclaration(declaration);
            var memberDeclaration = root.kind === 146 /* Parameter */ ? root.parent : root;
            return isPrivateWithinAmbient(memberDeclaration);
        }
        function getTypeOfVariableOrParameterOrProperty(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                // Handle prototype property
                if (symbol.flags & 4194304 /* Prototype */) {
                    return links.type = getTypeOfPrototypeProperty(symbol);
                }
                // Handle catch clause variables
                var declaration = symbol.valueDeclaration;
                if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
                    return links.type = anyType;
                }
                // Handle export default expressions
                if (declaration.kind === 243 /* ExportAssignment */) {
                    return links.type = checkExpression(declaration.expression);
                }
                if (ts.isInJavaScriptFile(declaration) && ts.isJSDocPropertyLikeTag(declaration) && declaration.typeExpression) {
                    return links.type = getTypeFromTypeNode(declaration.typeExpression.type);
                }
                // Handle variable, parameter or property
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return unknownType;
                }
                var type = void 0;
                // Handle certain special assignment kinds, which happen to union across multiple declarations:
                // * module.exports = expr
                // * exports.p = expr
                // * this.p = expr
                // * className.prototype.method = expr
                if (declaration.kind === 194 /* BinaryExpression */ ||
                    declaration.kind === 179 /* PropertyAccessExpression */ && declaration.parent.kind === 194 /* BinaryExpression */) {
                    type = getWidenedTypeFromJSSpecialPropertyDeclarations(symbol);
                }
                else {
                    type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true);
                }
                if (!popTypeResolution()) {
                    type = reportCircularityError(symbol);
                }
                links.type = type;
            }
            return links.type;
        }
        function getAnnotatedAccessorType(accessor) {
            if (accessor) {
                if (accessor.kind === 153 /* GetAccessor */) {
                    var getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor);
                    return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation);
                }
                else {
                    var setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor);
                    return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation);
                }
            }
            return undefined;
        }
        function getAnnotatedAccessorThisParameter(accessor) {
            var parameter = getAccessorThisParameter(accessor);
            return parameter && parameter.symbol;
        }
        function getThisTypeOfDeclaration(declaration) {
            return getThisTypeOfSignature(getSignatureFromDeclaration(declaration));
        }
        function getTypeOfAccessors(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var getter = ts.getDeclarationOfKind(symbol, 153 /* GetAccessor */);
                var setter = ts.getDeclarationOfKind(symbol, 154 /* SetAccessor */);
                if (getter && ts.isInJavaScriptFile(getter)) {
                    var jsDocType = getTypeForDeclarationFromJSDocComment(getter);
                    if (jsDocType) {
                        return links.type = jsDocType;
                    }
                }
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return unknownType;
                }
                var type = void 0;
                // First try to see if the user specified a return type on the get-accessor.
                var getterReturnType = getAnnotatedAccessorType(getter);
                if (getterReturnType) {
                    type = getterReturnType;
                }
                else {
                    // If the user didn't specify a return type, try to use the set-accessor's parameter type.
                    var setterParameterType = getAnnotatedAccessorType(setter);
                    if (setterParameterType) {
                        type = setterParameterType;
                    }
                    else {
                        // If there are no specified types, try to infer it from the body of the get accessor if it exists.
                        if (getter && getter.body) {
                            type = getReturnTypeFromBody(getter);
                        }
                        else {
                            if (noImplicitAny) {
                                if (setter) {
                                    error(setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
                                }
                                else {
                                    ts.Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
                                    error(getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
                                }
                            }
                            type = anyType;
                        }
                    }
                }
                if (!popTypeResolution()) {
                    type = anyType;
                    if (noImplicitAny) {
                        var getter_1 = ts.getDeclarationOfKind(symbol, 153 /* GetAccessor */);
                        error(getter_1, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
                    }
                }
                links.type = type;
            }
            return links.type;
        }
        function getBaseTypeVariableOfClass(symbol) {
            var baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol));
            return baseConstructorType.flags & 540672 /* TypeVariable */ ? baseConstructorType : undefined;
        }
        function getTypeOfFuncClassEnumModule(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                if (symbol.flags & 1536 /* Module */ && ts.isShorthandAmbientModuleSymbol(symbol)) {
                    links.type = anyType;
                }
                else {
                    var type = createObjectType(16 /* Anonymous */, symbol);
                    if (symbol.flags & 32 /* Class */) {
                        var baseTypeVariable = getBaseTypeVariableOfClass(symbol);
                        links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
                    }
                    else {
                        links.type = strictNullChecks && symbol.flags & 16777216 /* Optional */ ? getNullableType(type, 2048 /* Undefined */) : type;
                    }
                }
            }
            return links.type;
        }
        function getTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                links.type = getDeclaredTypeOfEnumMember(symbol);
            }
            return links.type;
        }
        function getTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var targetSymbol = resolveAlias(symbol);
                // It only makes sense to get the type of a value symbol. If the result of resolving
                // the alias is not a value, then it has no type. To get the type associated with a
                // type symbol, call getDeclaredTypeOfSymbol.
                // This check is important because without it, a call to getTypeOfSymbol could end
                // up recursively calling getTypeOfAlias, causing a stack overflow.
                links.type = targetSymbol.flags & 107455 /* Value */
                    ? getTypeOfSymbol(targetSymbol)
                    : unknownType;
            }
            return links.type;
        }
        function getTypeOfInstantiatedSymbol(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                if (symbolInstantiationDepth === 100) {
                    error(symbol.valueDeclaration, ts.Diagnostics.Generic_type_instantiation_is_excessively_deep_and_possibly_infinite);
                    links.type = unknownType;
                }
                else {
                    if (!pushTypeResolution(symbol, 0 /* Type */)) {
                        return unknownType;
                    }
                    symbolInstantiationDepth++;
                    var type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
                    symbolInstantiationDepth--;
                    if (!popTypeResolution()) {
                        type = reportCircularityError(symbol);
                    }
                    links.type = type;
                }
            }
            return links.type;
        }
        function reportCircularityError(symbol) {
            // Check if variable has type annotation that circularly references the variable itself
            if (ts.getEffectiveTypeAnnotationNode(symbol.valueDeclaration)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
                return unknownType;
            }
            // Otherwise variable has initializer that circularly references the variable itself
            if (noImplicitAny) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
            }
            return anyType;
        }
        function getTypeOfSymbol(symbol) {
            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                return getTypeOfInstantiatedSymbol(symbol);
            }
            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                return getTypeOfVariableOrParameterOrProperty(symbol);
            }
            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                return getTypeOfFuncClassEnumModule(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 98304 /* Accessor */) {
                return getTypeOfAccessors(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getTypeOfAlias(symbol);
            }
            return unknownType;
        }
        function isReferenceToType(type, target) {
            return type !== undefined
                && target !== undefined
                && (getObjectFlags(type) & 4 /* Reference */) !== 0
                && type.target === target;
        }
        function getTargetType(type) {
            return getObjectFlags(type) & 4 /* Reference */ ? type.target : type;
        }
        function hasBaseType(type, checkBase) {
            return check(type);
            function check(type) {
                if (getObjectFlags(type) & (3 /* ClassOrInterface */ | 4 /* Reference */)) {
                    var target = getTargetType(type);
                    return target === checkBase || ts.forEach(getBaseTypes(target), check);
                }
                else if (type.flags & 131072 /* Intersection */) {
                    return ts.forEach(type.types, check);
                }
            }
        }
        // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
        // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
        // in-place and returns the same array.
        function appendTypeParameters(typeParameters, declarations) {
            for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
                var declaration = declarations_2[_i];
                var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
                typeParameters = ts.appendIfUnique(typeParameters, tp);
            }
            return typeParameters;
        }
        // Return the outer type parameters of a node or undefined if the node has no outer type parameters.
        function getOuterTypeParameters(node, includeThisTypes) {
            while (true) {
                node = node.parent;
                if (!node) {
                    return undefined;
                }
                switch (node.kind) {
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 230 /* InterfaceDeclaration */:
                    case 155 /* CallSignature */:
                    case 156 /* ConstructSignature */:
                    case 150 /* MethodSignature */:
                    case 160 /* FunctionType */:
                    case 161 /* ConstructorType */:
                    case 273 /* JSDocFunctionType */:
                    case 228 /* FunctionDeclaration */:
                    case 151 /* MethodDeclaration */:
                    case 186 /* FunctionExpression */:
                    case 187 /* ArrowFunction */:
                    case 231 /* TypeAliasDeclaration */:
                    case 282 /* JSDocTemplateTag */:
                    case 172 /* MappedType */:
                        var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
                        if (node.kind === 172 /* MappedType */) {
                            return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)));
                        }
                        var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray);
                        var thisType = includeThisTypes &&
                            (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */ || node.kind === 230 /* InterfaceDeclaration */) &&
                            getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
                        return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
                }
            }
        }
        // The outer type parameters are those defined by enclosing generic classes, methods, or functions.
        function getOuterTypeParametersOfClassOrInterface(symbol) {
            var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230 /* InterfaceDeclaration */);
            return getOuterTypeParameters(declaration);
        }
        // The local type parameters are the combined set of type parameters from all declarations of the class,
        // interface, or type alias.
        function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) {
            var result;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var node = _a[_i];
                if (node.kind === 230 /* InterfaceDeclaration */ || node.kind === 229 /* ClassDeclaration */ ||
                    node.kind === 199 /* ClassExpression */ || node.kind === 231 /* TypeAliasDeclaration */) {
                    var declaration = node;
                    if (declaration.typeParameters) {
                        result = appendTypeParameters(result, declaration.typeParameters);
                    }
                }
            }
            return result;
        }
        // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
        // its locally declared type parameters.
        function getTypeParametersOfClassOrInterface(symbol) {
            return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
        }
        // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single
        // rest parameter of type any[].
        function isMixinConstructorType(type) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length === 1) {
                var s = signatures[0];
                return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType;
            }
            return false;
        }
        function isConstructorType(type) {
            if (isValidBaseType(type) && getSignaturesOfType(type, 1 /* Construct */).length > 0) {
                return true;
            }
            if (type.flags & 540672 /* TypeVariable */) {
                var constraint = getBaseConstraintOfType(type);
                return constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint);
            }
            return false;
        }
        function getBaseTypeNodeOfClass(type) {
            var decl = type.symbol.valueDeclaration;
            if (ts.isInJavaScriptFile(decl)) {
                // Prefer an @augments tag because it may have type parameters.
                var tag = ts.getJSDocAugmentsTag(decl);
                if (tag) {
                    return tag.class;
                }
            }
            return ts.getClassExtendsHeritageClauseElement(decl);
        }
        function getConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var typeArgCount = ts.length(typeArgumentNodes);
            var isJavaScript = ts.isInJavaScriptFile(location);
            return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters); });
        }
        function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
            var typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode);
            return ts.sameMap(signatures, function (sig) { return ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJavaScriptFile(location)) : sig; });
        }
        /**
         * The base constructor of a class can resolve to
         * * undefinedType if the class has no extends clause,
         * * unknownType if an error occurred during resolution of the extends expression,
         * * nullType if the extends expression is the null value,
         * * anyType if the extends expression has type any, or
         * * an object type with at least one construct signature.
         */
        function getBaseConstructorTypeOfClass(type) {
            if (!type.resolvedBaseConstructorType) {
                var decl = type.symbol.valueDeclaration;
                var extended = ts.getClassExtendsHeritageClauseElement(decl);
                var baseTypeNode = getBaseTypeNodeOfClass(type);
                if (!baseTypeNode) {
                    return type.resolvedBaseConstructorType = undefinedType;
                }
                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
                    return unknownType;
                }
                var baseConstructorType = checkExpression(baseTypeNode.expression);
                if (extended && baseTypeNode !== extended) {
                    ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
                    checkExpression(extended.expression);
                }
                if (baseConstructorType.flags & (32768 /* Object */ | 131072 /* Intersection */)) {
                    // Resolving the members of a class requires us to resolve the base class of that class.
                    // We force resolution here such that we catch circularities now.
                    resolveStructuredTypeMembers(baseConstructorType);
                }
                if (!popTypeResolution()) {
                    error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
                    return type.resolvedBaseConstructorType = unknownType;
                }
                if (!(baseConstructorType.flags & 1 /* Any */) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
                    error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
                    return type.resolvedBaseConstructorType = unknownType;
                }
                type.resolvedBaseConstructorType = baseConstructorType;
            }
            return type.resolvedBaseConstructorType;
        }
        function getBaseTypes(type) {
            if (!type.resolvedBaseTypes) {
                if (type.objectFlags & 8 /* Tuple */) {
                    type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))];
                }
                else if (type.symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                    if (type.symbol.flags & 32 /* Class */) {
                        resolveBaseTypesOfClass(type);
                    }
                    if (type.symbol.flags & 64 /* Interface */) {
                        resolveBaseTypesOfInterface(type);
                    }
                }
                else {
                    ts.Debug.fail("type must be class or interface");
                }
            }
            return type.resolvedBaseTypes;
        }
        function resolveBaseTypesOfClass(type) {
            type.resolvedBaseTypes = ts.emptyArray;
            var baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
            if (!(baseConstructorType.flags & (32768 /* Object */ | 131072 /* Intersection */ | 1 /* Any */))) {
                return;
            }
            var baseTypeNode = getBaseTypeNodeOfClass(type);
            var typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
            var baseType;
            var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
            if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
                areAllOuterTypeParametersApplied(originalBaseType)) {
                // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
                // class and all return the instance type of the class. There is no need for further checks and we can apply the
                // type arguments in the same manner as a type reference to get the same error reporting experience.
                baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs);
            }
            else if (baseConstructorType.flags & 1 /* Any */) {
                baseType = baseConstructorType;
            }
            else {
                // The class derives from a "class-like" constructor function, check that we have at least one construct signature
                // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
                // we check that all instantiated signatures return the same type.
                var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
                if (!constructors.length) {
                    error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
                    return;
                }
                baseType = getReturnTypeOfSignature(constructors[0]);
            }
            if (baseType === unknownType) {
                return;
            }
            if (!isValidBaseType(baseType)) {
                error(baseTypeNode.expression, ts.Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
                return;
            }
            if (type === baseType || hasBaseType(baseType, type)) {
                error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */));
                return;
            }
            type.resolvedBaseTypes = [baseType];
        }
        function areAllOuterTypeParametersApplied(type) {
            // An unapplied type parameter has its symbol still the same as the matching argument symbol.
            // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
            var outerTypeParameters = type.outerTypeParameters;
            if (outerTypeParameters) {
                var last_1 = outerTypeParameters.length - 1;
                var typeArguments = type.typeArguments;
                return outerTypeParameters[last_1].symbol !== typeArguments[last_1].symbol;
            }
            return true;
        }
        // A valid base type is `any`, any non-generic object type or intersection of non-generic
        // object types.
        function isValidBaseType(type) {
            return type.flags & (32768 /* Object */ | 16777216 /* NonPrimitive */ | 1 /* Any */) && !isGenericMappedType(type) ||
                type.flags & 131072 /* Intersection */ && !ts.forEach(type.types, function (t) { return !isValidBaseType(t); });
        }
        function resolveBaseTypesOfInterface(type) {
            type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 230 /* InterfaceDeclaration */ && ts.getInterfaceBaseTypeNodes(declaration)) {
                    for (var _b = 0, _c = ts.getInterfaceBaseTypeNodes(declaration); _b < _c.length; _b++) {
                        var node = _c[_b];
                        var baseType = getTypeFromTypeNode(node);
                        if (baseType !== unknownType) {
                            if (isValidBaseType(baseType)) {
                                if (type !== baseType && !hasBaseType(baseType, type)) {
                                    if (type.resolvedBaseTypes === ts.emptyArray) {
                                        type.resolvedBaseTypes = [baseType];
                                    }
                                    else {
                                        type.resolvedBaseTypes.push(baseType);
                                    }
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */));
                                }
                            }
                            else {
                                error(node, ts.Diagnostics.An_interface_may_only_extend_a_class_or_another_interface);
                            }
                        }
                    }
                }
            }
        }
        // Returns true if the interface given by the symbol is free of "this" references. Specifically, the result is
        // true if the interface itself contains no references to "this" in its body, if all base types are interfaces,
        // and if none of the base interfaces have a "this" type.
        function isIndependentInterface(symbol) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 230 /* InterfaceDeclaration */) {
                    if (declaration.flags & 64 /* ContainsThis */) {
                        return false;
                    }
                    var baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration);
                    if (baseTypeNodes) {
                        for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) {
                            var node = baseTypeNodes_1[_b];
                            if (ts.isEntityNameExpression(node.expression)) {
                                var baseSymbol = resolveEntityName(node.expression, 793064 /* Type */, /*ignoreErrors*/ true);
                                if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }
        function getDeclaredTypeOfClassOrInterface(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var kind = symbol.flags & 32 /* Class */ ? 1 /* Class */ : 2 /* Interface */;
                var type = links.declaredType = createObjectType(kind, symbol);
                var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol);
                var localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type
                // because it is not feasible to analyze all members to determine if the "this" type escapes the class (in particular,
                // property types inferred from initializers and method return types inferred from return statements are very hard
                // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of
                // "this" references.
                if (outerTypeParameters || localTypeParameters || kind === 1 /* Class */ || !isIndependentInterface(symbol)) {
                    type.objectFlags |= 4 /* Reference */;
                    type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters);
                    type.outerTypeParameters = outerTypeParameters;
                    type.localTypeParameters = localTypeParameters;
                    type.instantiations = ts.createMap();
                    type.instantiations.set(getTypeListId(type.typeParameters), type);
                    type.target = type;
                    type.typeArguments = type.typeParameters;
                    type.thisType = createType(16384 /* TypeParameter */);
                    type.thisType.isThisType = true;
                    type.thisType.symbol = symbol;
                    type.thisType.constraint = type;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                // Note that we use the links object as the target here because the symbol object is used as the unique
                // identity for resolution of the 'type' property in SymbolLinks.
                if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) {
                    return unknownType;
                }
                var declaration = ts.find(symbol.declarations, function (d) {
                    return d.kind === 283 /* JSDocTypedefTag */ || d.kind === 231 /* TypeAliasDeclaration */;
                });
                var typeNode = declaration.kind === 283 /* JSDocTypedefTag */ ? declaration.typeExpression : declaration.type;
                // If typeNode is missing, we will error in checkJSDocTypedefTag.
                var type = typeNode ? getTypeFromTypeNode(typeNode) : unknownType;
                if (popTypeResolution()) {
                    var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    if (typeParameters) {
                        // Initialize the instantiation cache for generic type aliases. The declared type corresponds to
                        // an instantiation of the type alias with the type parameters supplied as type arguments.
                        links.typeParameters = typeParameters;
                        links.instantiations = ts.createMap();
                        links.instantiations.set(getTypeListId(typeParameters), type);
                    }
                }
                else {
                    type = unknownType;
                    error(declaration.name, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
                }
                links.declaredType = type;
            }
            return links.declaredType;
        }
        function isLiteralEnumMember(member) {
            var expr = member.initializer;
            if (!expr) {
                return !ts.isInAmbientContext(member);
            }
            switch (expr.kind) {
                case 9 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                    return true;
                case 192 /* PrefixUnaryExpression */:
                    return expr.operator === 38 /* MinusToken */ &&
                        expr.operand.kind === 8 /* NumericLiteral */;
                case 71 /* Identifier */:
                    return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get(expr.escapedText);
                default:
                    return false;
            }
        }
        function getEnumKind(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.enumKind !== undefined) {
                return links.enumKind;
            }
            var hasNonLiteralMember = false;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 232 /* EnumDeclaration */) {
                    for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                        var member = _c[_b];
                        if (member.initializer && member.initializer.kind === 9 /* StringLiteral */) {
                            return links.enumKind = 1 /* Literal */;
                        }
                        if (!isLiteralEnumMember(member)) {
                            hasNonLiteralMember = true;
                        }
                    }
                }
            }
            return links.enumKind = hasNonLiteralMember ? 0 /* Numeric */ : 1 /* Literal */;
        }
        function getBaseTypeOfEnumLiteralType(type) {
            return type.flags & 256 /* EnumLiteral */ && !(type.flags & 65536 /* Union */) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type;
        }
        function getDeclaredTypeOfEnum(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.declaredType) {
                return links.declaredType;
            }
            if (getEnumKind(symbol) === 1 /* Literal */) {
                enumCount++;
                var memberTypeList = [];
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.kind === 232 /* EnumDeclaration */) {
                        for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                            var member = _c[_b];
                            var memberType = getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member));
                            getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
                            memberTypeList.push(memberType);
                        }
                    }
                }
                if (memberTypeList.length) {
                    var enumType_1 = getUnionType(memberTypeList, /*subtypeReduction*/ false, symbol, /*aliasTypeArguments*/ undefined);
                    if (enumType_1.flags & 65536 /* Union */) {
                        enumType_1.flags |= 256 /* EnumLiteral */;
                        enumType_1.symbol = symbol;
                    }
                    return links.declaredType = enumType_1;
                }
            }
            var enumType = createType(16 /* Enum */);
            enumType.symbol = symbol;
            return links.declaredType = enumType;
        }
        function getDeclaredTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
                if (!links.declaredType) {
                    links.declaredType = enumType;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeParameter(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var type = createType(16384 /* TypeParameter */);
                type.symbol = symbol;
                links.declaredType = type;
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol));
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfSymbol(symbol) {
            return tryGetDeclaredTypeOfSymbol(symbol) || unknownType;
        }
        function tryGetDeclaredTypeOfSymbol(symbol) {
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getDeclaredTypeOfClassOrInterface(symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getDeclaredTypeOfTypeAlias(symbol);
            }
            if (symbol.flags & 262144 /* TypeParameter */) {
                return getDeclaredTypeOfTypeParameter(symbol);
            }
            if (symbol.flags & 384 /* Enum */) {
                return getDeclaredTypeOfEnum(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getDeclaredTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getDeclaredTypeOfAlias(symbol);
            }
            return undefined;
        }
        // A type reference is considered independent if each type argument is considered independent.
        function isIndependentTypeReference(node) {
            if (node.typeArguments) {
                for (var _i = 0, _a = node.typeArguments; _i < _a.length; _i++) {
                    var typeNode = _a[_i];
                    if (!isIndependentType(typeNode)) {
                        return false;
                    }
                }
            }
            return true;
        }
        // A type is considered independent if it the any, string, number, boolean, symbol, or void keyword, a string
        // literal type, an array with an element type that is considered independent, or a type reference that is
        // considered independent.
        function isIndependentType(node) {
            switch (node.kind) {
                case 119 /* AnyKeyword */:
                case 136 /* StringKeyword */:
                case 133 /* NumberKeyword */:
                case 122 /* BooleanKeyword */:
                case 137 /* SymbolKeyword */:
                case 134 /* ObjectKeyword */:
                case 105 /* VoidKeyword */:
                case 139 /* UndefinedKeyword */:
                case 95 /* NullKeyword */:
                case 130 /* NeverKeyword */:
                case 173 /* LiteralType */:
                    return true;
                case 164 /* ArrayType */:
                    return isIndependentType(node.elementType);
                case 159 /* TypeReference */:
                    return isIndependentTypeReference(node);
            }
            return false;
        }
        // A variable-like declaration is considered independent (free of this references) if it has a type annotation
        // that specifies an independent type, or if it has no type annotation and no initializer (and thus of type any).
        function isIndependentVariableLikeDeclaration(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return typeNode ? isIndependentType(typeNode) : !node.initializer;
        }
        // A function-like declaration is considered independent (free of this references) if it has a return type
        // annotation that is considered independent and if each parameter is considered independent.
        function isIndependentFunctionLikeDeclaration(node) {
            if (node.kind !== 152 /* Constructor */) {
                var typeNode = ts.getEffectiveReturnTypeNode(node);
                if (!typeNode || !isIndependentType(typeNode)) {
                    return false;
                }
            }
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                if (!isIndependentVariableLikeDeclaration(parameter)) {
                    return false;
                }
            }
            return true;
        }
        // Returns true if the class or interface member given by the symbol is free of "this" references. The
        // function may return false for symbols that are actually free of "this" references because it is not
        // feasible to perform a complete analysis in all cases. In particular, property members with types
        // inferred from their initializers and function members with inferred return types are conservatively
        // assumed not to be free of "this" references.
        function isIndependentMember(symbol) {
            if (symbol.declarations && symbol.declarations.length === 1) {
                var declaration = symbol.declarations[0];
                if (declaration) {
                    switch (declaration.kind) {
                        case 149 /* PropertyDeclaration */:
                        case 148 /* PropertySignature */:
                            return isIndependentVariableLikeDeclaration(declaration);
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                        case 152 /* Constructor */:
                            return isIndependentFunctionLikeDeclaration(declaration);
                    }
                }
            }
            return false;
        }
        // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true,
        // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.
        function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) {
            var result = ts.createSymbolTable();
            for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                var symbol = symbols_2[_i];
                result.set(symbol.escapedName, mappingThisOnly && isIndependentMember(symbol) ? symbol : instantiateSymbol(symbol, mapper));
            }
            return result;
        }
        function addInheritedMembers(symbols, baseSymbols) {
            for (var _i = 0, baseSymbols_1 = baseSymbols; _i < baseSymbols_1.length; _i++) {
                var s = baseSymbols_1[_i];
                if (!symbols.has(s.escapedName)) {
                    symbols.set(s.escapedName, s);
                }
            }
        }
        function resolveDeclaredMembers(type) {
            if (!type.declaredProperties) {
                var symbol = type.symbol;
                type.declaredProperties = getNamedMembers(symbol.members);
                type.declaredCallSignatures = getSignaturesOfSymbol(symbol.members.get("__call" /* Call */));
                type.declaredConstructSignatures = getSignaturesOfSymbol(symbol.members.get("__new" /* New */));
                type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
            }
            return type;
        }
        function getTypeWithThisArgument(type, thisArgument) {
            if (getObjectFlags(type) & 4 /* Reference */) {
                var target = type.target;
                var typeArguments = type.typeArguments;
                if (ts.length(target.typeParameters) === ts.length(typeArguments)) {
                    return createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType]));
                }
            }
            else if (type.flags & 131072 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return getTypeWithThisArgument(t, thisArgument); }));
            }
            return type;
        }
        function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) {
            var mapper;
            var members;
            var callSignatures;
            var constructSignatures;
            var stringIndexInfo;
            var numberIndexInfo;
            if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
                mapper = identityMapper;
                members = source.symbol ? source.symbol.members : ts.createSymbolTable(source.declaredProperties);
                callSignatures = source.declaredCallSignatures;
                constructSignatures = source.declaredConstructSignatures;
                stringIndexInfo = source.declaredStringIndexInfo;
                numberIndexInfo = source.declaredNumberIndexInfo;
            }
            else {
                mapper = createTypeMapper(typeParameters, typeArguments);
                members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
                callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
                constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
                stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
                numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
            }
            var baseTypes = getBaseTypes(source);
            if (baseTypes.length) {
                if (source.symbol && members === source.symbol.members) {
                    members = ts.createSymbolTable(source.declaredProperties);
                }
                var thisArgument = ts.lastOrUndefined(typeArguments);
                for (var _i = 0, baseTypes_1 = baseTypes; _i < baseTypes_1.length; _i++) {
                    var baseType = baseTypes_1[_i];
                    var instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
                    addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType));
                    callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
                    constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
                    if (!stringIndexInfo) {
                        stringIndexInfo = instantiatedBaseType === anyType ?
                            createIndexInfo(anyType, /*isReadonly*/ false) :
                            getIndexInfoOfType(instantiatedBaseType, 0 /* String */);
                    }
                    numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */);
                }
            }
            setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function resolveClassOrInterfaceMembers(type) {
            resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray);
        }
        function resolveTypeReferenceMembers(type) {
            var source = resolveDeclaredMembers(type.target);
            var typeParameters = ts.concatenate(source.typeParameters, [source.thisType]);
            var typeArguments = type.typeArguments && type.typeArguments.length === typeParameters.length ?
                type.typeArguments : ts.concatenate(type.typeArguments, [type]);
            resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
        }
        function createSignature(declaration, typeParameters, thisParameter, parameters, resolvedReturnType, typePredicate, minArgumentCount, hasRestParameter, hasLiteralTypes) {
            var sig = new Signature(checker);
            sig.declaration = declaration;
            sig.typeParameters = typeParameters;
            sig.parameters = parameters;
            sig.thisParameter = thisParameter;
            sig.resolvedReturnType = resolvedReturnType;
            sig.typePredicate = typePredicate;
            sig.minArgumentCount = minArgumentCount;
            sig.hasRestParameter = hasRestParameter;
            sig.hasLiteralTypes = hasLiteralTypes;
            return sig;
        }
        function cloneSignature(sig) {
            return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
        }
        function getDefaultConstructSignatures(classType) {
            var baseConstructorType = getBaseConstructorTypeOfClass(classType);
            var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */);
            if (baseSignatures.length === 0) {
                return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
            }
            var baseTypeNode = getBaseTypeNodeOfClass(classType);
            var isJavaScript = ts.isInJavaScriptFile(baseTypeNode);
            var typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode);
            var typeArgCount = ts.length(typeArguments);
            var result = [];
            for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) {
                var baseSig = baseSignatures_1[_i];
                var minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
                var typeParamCount = ts.length(baseSig.typeParameters);
                if ((isJavaScript || typeArgCount >= minTypeArgumentCount) && typeArgCount <= typeParamCount) {
                    var sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
                    sig.typeParameters = classType.localTypeParameters;
                    sig.resolvedReturnType = classType;
                    result.push(sig);
                }
            }
            return result;
        }
        function findMatchingSignature(signatureList, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes) {
            for (var _i = 0, signatureList_1 = signatureList; _i < signatureList_1.length; _i++) {
                var s = signatureList_1[_i];
                if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypesIdentical)) {
                    return s;
                }
            }
        }
        function findMatchingSignatures(signatureLists, signature, listIndex) {
            if (signature.typeParameters) {
                // We require an exact match for generic signatures, so we only return signatures from the first
                // signature list and only if they have exact matches in the other signature lists.
                if (listIndex > 0) {
                    return undefined;
                }
                for (var i = 1; i < signatureLists.length; i++) {
                    if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false)) {
                        return undefined;
                    }
                }
                return [signature];
            }
            var result = undefined;
            for (var i = 0; i < signatureLists.length; i++) {
                // Allow matching non-generic signatures to have excess parameters and different return types
                var match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true);
                if (!match) {
                    return undefined;
                }
                result = ts.appendIfUnique(result, match);
            }
            return result;
        }
        // The signatures of a union type are those signatures that are present in each of the constituent types.
        // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional
        // parameters and may differ in return types. When signatures differ in return types, the resulting return
        // type is the union of the constituent return types.
        function getUnionSignatures(types, kind) {
            var signatureLists = ts.map(types, function (t) { return getSignaturesOfType(t, kind); });
            var result = undefined;
            for (var i = 0; i < signatureLists.length; i++) {
                for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    // Only process signatures with parameter lists that aren't already in the result list
                    if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true)) {
                        var unionSignatures = findMatchingSignatures(signatureLists, signature, i);
                        if (unionSignatures) {
                            var s = signature;
                            // Union the result types when more than one signature matches
                            if (unionSignatures.length > 1) {
                                s = cloneSignature(signature);
                                if (ts.forEach(unionSignatures, function (sig) { return sig.thisParameter; })) {
                                    var thisType = getUnionType(ts.map(unionSignatures, function (sig) { return getTypeOfSymbol(sig.thisParameter) || anyType; }), /*subtypeReduction*/ true);
                                    s.thisParameter = createSymbolWithType(signature.thisParameter, thisType);
                                }
                                // Clear resolved return type we possibly got from cloneSignature
                                s.resolvedReturnType = undefined;
                                s.unionSignatures = unionSignatures;
                            }
                            (result || (result = [])).push(s);
                        }
                    }
                }
            }
            return result || ts.emptyArray;
        }
        function getUnionIndexInfo(types, kind) {
            var indexTypes = [];
            var isAnyReadonly = false;
            for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
                var type = types_1[_i];
                var indexInfo = getIndexInfoOfType(type, kind);
                if (!indexInfo) {
                    return undefined;
                }
                indexTypes.push(indexInfo.type);
                isAnyReadonly = isAnyReadonly || indexInfo.isReadonly;
            }
            return createIndexInfo(getUnionType(indexTypes, /*subtypeReduction*/ true), isAnyReadonly);
        }
        function resolveUnionTypeMembers(type) {
            // The members and properties collections are empty for union types. To get all properties of a union
            // type use getPropertiesOfType (only the language service uses this).
            var callSignatures = getUnionSignatures(type.types, 0 /* Call */);
            var constructSignatures = getUnionSignatures(type.types, 1 /* Construct */);
            var stringIndexInfo = getUnionIndexInfo(type.types, 0 /* String */);
            var numberIndexInfo = getUnionIndexInfo(type.types, 1 /* Number */);
            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function intersectTypes(type1, type2) {
            return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]);
        }
        function intersectIndexInfos(info1, info2) {
            return !info1 ? info2 : !info2 ? info1 : createIndexInfo(getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
        }
        function unionSpreadIndexInfos(info1, info2) {
            return info1 && info2 && createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
        }
        function includeMixinType(type, types, index) {
            var mixedTypes = [];
            for (var i = 0; i < types.length; i++) {
                if (i === index) {
                    mixedTypes.push(type);
                }
                else if (isMixinConstructorType(types[i])) {
                    mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], 1 /* Construct */)[0]));
                }
            }
            return getIntersectionType(mixedTypes);
        }
        function resolveIntersectionTypeMembers(type) {
            // The members and properties collections are empty for intersection types. To get all properties of an
            // intersection type use getPropertiesOfType (only the language service uses this).
            var callSignatures = ts.emptyArray;
            var constructSignatures = ts.emptyArray;
            var stringIndexInfo;
            var numberIndexInfo;
            var types = type.types;
            var mixinCount = ts.countWhere(types, isMixinConstructorType);
            var _loop_3 = function (i) {
                var t = type.types[i];
                // When an intersection type contains mixin constructor types, the construct signatures from
                // those types are discarded and their return types are mixed into the return types of all
                // other construct signatures in the intersection type. For example, the intersection type
                // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
                // 'new(s: string) => A & B'.
                if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t)) {
                    var signatures = getSignaturesOfType(t, 1 /* Construct */);
                    if (signatures.length && mixinCount > 0) {
                        signatures = ts.map(signatures, function (s) {
                            var clone = cloneSignature(s);
                            clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i);
                            return clone;
                        });
                    }
                    constructSignatures = ts.concatenate(constructSignatures, signatures);
                }
                callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(t, 0 /* Call */));
                stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */));
                numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */));
            };
            for (var i = 0; i < types.length; i++) {
                _loop_3(i);
            }
            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        /**
         * Converts an AnonymousType to a ResolvedType.
         */
        function resolveAnonymousTypeMembers(type) {
            var symbol = type.symbol;
            if (type.target) {
                var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
                var callSignatures = instantiateSignatures(getSignaturesOfType(type.target, 0 /* Call */), type.mapper);
                var constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper);
                var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper);
                var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else if (symbol.flags & 2048 /* TypeLiteral */) {
                var members = symbol.members;
                var callSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                var constructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else {
                // Combinations of function, class, enum and module
                var members = emptySymbols;
                var stringIndexInfo = undefined;
                if (symbol.exports) {
                    members = getExportsOfSymbol(symbol);
                }
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var baseConstructorType = getBaseConstructorTypeOfClass(classType);
                    if (baseConstructorType.flags & (32768 /* Object */ | 131072 /* Intersection */ | 540672 /* TypeVariable */)) {
                        members = ts.createSymbolTable(getNamedMembers(members));
                        addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
                    }
                    else if (baseConstructorType === anyType) {
                        stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    }
                }
                var numberIndexInfo = symbol.flags & 384 /* Enum */ ? enumNumberIndexInfo : undefined;
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                // We resolve the members before computing the signatures because a signature may use
                // typeof with a qualified name expression that circularly references the type we are
                // in the process of resolving (see issue #6072). The temporarily empty signature list
                // will never be observed because a qualified name can't reference signatures.
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) {
                    type.callSignatures = getSignaturesOfSymbol(symbol);
                }
                // And likewise for construct signatures for classes
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var constructSignatures = getSignaturesOfSymbol(symbol.members.get("__constructor" /* Constructor */));
                    if (!constructSignatures.length) {
                        constructSignatures = getDefaultConstructSignatures(classType);
                    }
                    type.constructSignatures = constructSignatures;
                }
            }
        }
        /** Resolve the members of a mapped type { [P in K]: T } */
        function resolveMappedTypeMembers(type) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            // Resolve upfront such that recursive references see an empty object type.
            setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
            // and T as the template type.
            var typeParameter = getTypeParameterFromMappedType(type);
            var constraintType = getConstraintTypeFromMappedType(type);
            var templateType = getTemplateTypeFromMappedType(type);
            var modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
            var templateReadonly = !!type.declaration.readonlyToken;
            var templateOptional = !!type.declaration.questionToken;
            if (type.declaration.typeParameter.constraint.kind === 170 /* TypeOperator */) {
                // We have a { [P in keyof T]: X }
                for (var _i = 0, _a = getPropertiesOfType(modifiersType); _i < _a.length; _i++) {
                    var propertySymbol = _a[_i];
                    addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol);
                }
                if (modifiersType.flags & 1 /* Any */ || getIndexInfoOfType(modifiersType, 0 /* String */)) {
                    addMemberForKeyType(stringType);
                }
            }
            else {
                // First, if the constraint type is a type parameter, obtain the base constraint. Then,
                // if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
                // Finally, iterate over the constituents of the resulting iteration type.
                var keyType = constraintType.flags & 540672 /* TypeVariable */ ? getApparentType(constraintType) : constraintType;
                var iterationType = keyType.flags & 262144 /* Index */ ? getIndexType(getApparentType(keyType.type)) : keyType;
                forEachType(iterationType, addMemberForKeyType);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
            function addMemberForKeyType(t, propertySymbolOrIndex) {
                var propertySymbol;
                // forEachType delegates to forEach, which calls with a numeric second argument
                //  the type system currently doesn't catch this incompatibility, so we annotate
                //  the function ourselves to indicate the runtime behavior and deal with it here
                if (typeof propertySymbolOrIndex === "object") {
                    propertySymbol = propertySymbolOrIndex;
                }
                // Create a mapper from T to the current iteration type constituent. Then, if the
                // mapped type is itself an instantiated type, combine the iteration mapper with the
                // instantiation mapper.
                var iterationMapper = createTypeMapper([typeParameter], [t]);
                var templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper;
                var propType = instantiateType(templateType, templateMapper);
                // If the current iteration type constituent is a string literal type, create a property.
                // Otherwise, for type string create a string index signature.
                if (t.flags & 32 /* StringLiteral */) {
                    var propName = ts.escapeLeadingUnderscores(t.value);
                    var modifiersProp = getPropertyOfType(modifiersType, propName);
                    var isOptional = templateOptional || !!(modifiersProp && modifiersProp.flags & 16777216 /* Optional */);
                    var prop = createSymbol(4 /* Property */ | (isOptional ? 16777216 /* Optional */ : 0), propName);
                    prop.checkFlags = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp) ? 8 /* Readonly */ : 0;
                    prop.type = propType;
                    if (propertySymbol) {
                        prop.syntheticOrigin = propertySymbol;
                        prop.declarations = propertySymbol.declarations;
                    }
                    prop.syntheticLiteralTypeOrigin = t;
                    members.set(propName, prop);
                }
                else if (t.flags & (1 /* Any */ | 2 /* String */)) {
                    stringIndexInfo = createIndexInfo(propType, templateReadonly);
                }
            }
        }
        function getTypeParameterFromMappedType(type) {
            return type.typeParameter ||
                (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
        }
        function getConstraintTypeFromMappedType(type) {
            return type.constraintType ||
                (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType);
        }
        function getTemplateTypeFromMappedType(type) {
            return type.templateType ||
                (type.templateType = type.declaration.type ?
                    instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) :
                    unknownType);
        }
        function getModifiersTypeFromMappedType(type) {
            if (!type.modifiersType) {
                var constraintDeclaration = type.declaration.typeParameter.constraint;
                if (constraintDeclaration.kind === 170 /* TypeOperator */) {
                    // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
                    // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
                    // 'keyof T' to a literal union type and we can't recover T from that type.
                    type.modifiersType = instantiateType(getTypeFromTypeNode(constraintDeclaration.type), type.mapper || identityMapper);
                }
                else {
                    // Otherwise, get the declared constraint type, and if the constraint type is a type parameter,
                    // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T',
                    // the modifiers type is T. Otherwise, the modifiers type is {}.
                    var declaredType = getTypeFromMappedTypeNode(type.declaration);
                    var constraint = getConstraintTypeFromMappedType(declaredType);
                    var extendedConstraint = constraint && constraint.flags & 16384 /* TypeParameter */ ? getConstraintOfTypeParameter(constraint) : constraint;
                    type.modifiersType = extendedConstraint && extendedConstraint.flags & 262144 /* Index */ ? instantiateType(extendedConstraint.type, type.mapper || identityMapper) : emptyObjectType;
                }
            }
            return type.modifiersType;
        }
        function isPartialMappedType(type) {
            return getObjectFlags(type) & 32 /* Mapped */ && !!type.declaration.questionToken;
        }
        function isGenericMappedType(type) {
            return getObjectFlags(type) & 32 /* Mapped */ && isGenericIndexType(getConstraintTypeFromMappedType(type));
        }
        function resolveStructuredTypeMembers(type) {
            if (!type.members) {
                if (type.flags & 32768 /* Object */) {
                    if (type.objectFlags & 4 /* Reference */) {
                        resolveTypeReferenceMembers(type);
                    }
                    else if (type.objectFlags & 3 /* ClassOrInterface */) {
                        resolveClassOrInterfaceMembers(type);
                    }
                    else if (type.objectFlags & 16 /* Anonymous */) {
                        resolveAnonymousTypeMembers(type);
                    }
                    else if (type.objectFlags & 32 /* Mapped */) {
                        resolveMappedTypeMembers(type);
                    }
                }
                else if (type.flags & 65536 /* Union */) {
                    resolveUnionTypeMembers(type);
                }
                else if (type.flags & 131072 /* Intersection */) {
                    resolveIntersectionTypeMembers(type);
                }
            }
            return type;
        }
        /** Return properties of an object type or an empty array for other types */
        function getPropertiesOfObjectType(type) {
            if (type.flags & 32768 /* Object */) {
                return resolveStructuredTypeMembers(type).properties;
            }
            return ts.emptyArray;
        }
        /** If the given type is an object type and that type has a property by the given name,
         * return the symbol for that property. Otherwise return undefined.
         */
        function getPropertyOfObjectType(type, name) {
            if (type.flags & 32768 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
            }
        }
        function getPropertiesOfUnionOrIntersectionType(type) {
            if (!type.resolvedProperties) {
                var members = ts.createSymbolTable();
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var current = _a[_i];
                    for (var _b = 0, _c = getPropertiesOfType(current); _b < _c.length; _b++) {
                        var prop = _c[_b];
                        if (!members.has(prop.escapedName)) {
                            var combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.escapedName);
                            if (combinedProp) {
                                members.set(prop.escapedName, combinedProp);
                            }
                        }
                    }
                    // The properties of a union type are those that are present in all constituent types, so
                    // we only need to check the properties of the first type
                    if (type.flags & 65536 /* Union */) {
                        break;
                    }
                }
                type.resolvedProperties = getNamedMembers(members);
            }
            return type.resolvedProperties;
        }
        function getPropertiesOfType(type) {
            type = getApparentType(type);
            return type.flags & 196608 /* UnionOrIntersection */ ?
                getPropertiesOfUnionOrIntersectionType(type) :
                getPropertiesOfObjectType(type);
        }
        function getAllPossiblePropertiesOfTypes(types) {
            var unionType = getUnionType(types);
            if (!(unionType.flags & 65536 /* Union */)) {
                return getPropertiesOfType(unionType);
            }
            var props = ts.createSymbolTable();
            for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
                var memberType = types_2[_i];
                for (var _a = 0, _b = getPropertiesOfType(memberType); _a < _b.length; _a++) {
                    var escapedName = _b[_a].escapedName;
                    if (!props.has(escapedName)) {
                        props.set(escapedName, createUnionOrIntersectionProperty(unionType, escapedName));
                    }
                }
            }
            return ts.arrayFrom(props.values());
        }
        function getConstraintOfType(type) {
            return type.flags & 16384 /* TypeParameter */ ? getConstraintOfTypeParameter(type) :
                type.flags & 524288 /* IndexedAccess */ ? getConstraintOfIndexedAccess(type) :
                    getBaseConstraintOfType(type);
        }
        function getConstraintOfTypeParameter(typeParameter) {
            return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
        }
        function getConstraintOfIndexedAccess(type) {
            var transformed = getTransformedIndexedAccessType(type);
            if (transformed) {
                return transformed;
            }
            var baseObjectType = getBaseConstraintOfType(type.objectType);
            var baseIndexType = getBaseConstraintOfType(type.indexType);
            return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined;
        }
        function getBaseConstraintOfType(type) {
            if (type.flags & (540672 /* TypeVariable */ | 196608 /* UnionOrIntersection */)) {
                var constraint = getResolvedBaseConstraint(type);
                if (constraint !== noConstraintType && constraint !== circularConstraintType) {
                    return constraint;
                }
            }
            else if (type.flags & 262144 /* Index */) {
                return stringType;
            }
            return undefined;
        }
        function hasNonCircularBaseConstraint(type) {
            return getResolvedBaseConstraint(type) !== circularConstraintType;
        }
        /**
         * Return the resolved base constraint of a type variable. The noConstraintType singleton is returned if the
         * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint
         * circularly references the type variable.
         */
        function getResolvedBaseConstraint(type) {
            var typeStack;
            var circular;
            if (!type.resolvedBaseConstraint) {
                typeStack = [];
                var constraint = getBaseConstraint(type);
                type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type);
            }
            return type.resolvedBaseConstraint;
            function getBaseConstraint(t) {
                if (ts.contains(typeStack, t)) {
                    circular = true;
                    return undefined;
                }
                typeStack.push(t);
                var result = computeBaseConstraint(t);
                typeStack.pop();
                return result;
            }
            function computeBaseConstraint(t) {
                if (t.flags & 16384 /* TypeParameter */) {
                    var constraint = getConstraintFromTypeParameter(t);
                    return t.isThisType ? constraint :
                        constraint ? getBaseConstraint(constraint) : undefined;
                }
                if (t.flags & 196608 /* UnionOrIntersection */) {
                    var types = t.types;
                    var baseTypes = [];
                    for (var _i = 0, types_3 = types; _i < types_3.length; _i++) {
                        var type_2 = types_3[_i];
                        var baseType = getBaseConstraint(type_2);
                        if (baseType) {
                            baseTypes.push(baseType);
                        }
                    }
                    return t.flags & 65536 /* Union */ && baseTypes.length === types.length ? getUnionType(baseTypes) :
                        t.flags & 131072 /* Intersection */ && baseTypes.length ? getIntersectionType(baseTypes) :
                            undefined;
                }
                if (t.flags & 262144 /* Index */) {
                    return stringType;
                }
                if (t.flags & 524288 /* IndexedAccess */) {
                    var transformed = getTransformedIndexedAccessType(t);
                    if (transformed) {
                        return getBaseConstraint(transformed);
                    }
                    var baseObjectType = getBaseConstraint(t.objectType);
                    var baseIndexType = getBaseConstraint(t.indexType);
                    var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined;
                    return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined;
                }
                if (isGenericMappedType(t)) {
                    return emptyObjectType;
                }
                return t;
            }
        }
        function getApparentTypeOfIntersectionType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
        }
        function getResolvedTypeParameterDefault(typeParameter) {
            if (!typeParameter.default) {
                if (typeParameter.target) {
                    var targetDefault = getResolvedTypeParameterDefault(typeParameter.target);
                    typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType;
                }
                else {
                    // To block recursion, set the initial value to the resolvingDefaultType.
                    typeParameter.default = resolvingDefaultType;
                    var defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; });
                    var defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType;
                    if (typeParameter.default === resolvingDefaultType) {
                        // If we have not been called recursively, set the correct default type.
                        typeParameter.default = defaultType;
                    }
                }
            }
            else if (typeParameter.default === resolvingDefaultType) {
                // If we are called recursively for this type parameter, mark the default as circular.
                typeParameter.default = circularConstraintType;
            }
            return typeParameter.default;
        }
        /**
         * Gets the default type for a type parameter.
         *
         * If the type parameter is the result of an instantiation, this gets the instantiated
         * default type of its target. If the type parameter has no default type or the default is
         * circular, `undefined` is returned.
         */
        function getDefaultFromTypeParameter(typeParameter) {
            var defaultType = getResolvedTypeParameterDefault(typeParameter);
            return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined;
        }
        function hasNonCircularTypeParameterDefault(typeParameter) {
            return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType;
        }
        /**
         * Indicates whether the declaration of a typeParameter has a default type.
         */
        function hasTypeParameterDefault(typeParameter) {
            return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; }));
        }
        /**
         * For a type parameter, return the base constraint of the type parameter. For the string, number,
         * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
         * type itself. Note that the apparent type of a union type is the union type itself.
         */
        function getApparentType(type) {
            var t = type.flags & 540672 /* TypeVariable */ ? getBaseConstraintOfType(type) || emptyObjectType : type;
            return t.flags & 131072 /* Intersection */ ? getApparentTypeOfIntersectionType(t) :
                t.flags & 262178 /* StringLike */ ? globalStringType :
                    t.flags & 84 /* NumberLike */ ? globalNumberType :
                        t.flags & 136 /* BooleanLike */ ? globalBooleanType :
                            t.flags & 512 /* ESSymbol */ ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= 2 /* ES2015 */) :
                                t.flags & 16777216 /* NonPrimitive */ ? emptyObjectType :
                                    t;
        }
        function createUnionOrIntersectionProperty(containingType, name) {
            var props;
            var types = containingType.types;
            var isUnion = containingType.flags & 65536 /* Union */;
            var excludeModifiers = isUnion ? 24 /* NonPublicAccessibilityModifier */ : 0;
            // Flags we want to propagate to the result if they exist in all source symbols
            var commonFlags = isUnion ? 0 /* None */ : 16777216 /* Optional */;
            var syntheticFlag = 4 /* SyntheticMethod */;
            var checkFlags = 0;
            for (var _i = 0, types_4 = types; _i < types_4.length; _i++) {
                var current = types_4[_i];
                var type = getApparentType(current);
                if (type !== unknownType) {
                    var prop = getPropertyOfType(type, name);
                    var modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0;
                    if (prop && !(modifiers & excludeModifiers)) {
                        commonFlags &= prop.flags;
                        props = ts.appendIfUnique(props, prop);
                        checkFlags |= (isReadonlySymbol(prop) ? 8 /* Readonly */ : 0) |
                            (!(modifiers & 24 /* NonPublicAccessibilityModifier */) ? 64 /* ContainsPublic */ : 0) |
                            (modifiers & 16 /* Protected */ ? 128 /* ContainsProtected */ : 0) |
                            (modifiers & 8 /* Private */ ? 256 /* ContainsPrivate */ : 0) |
                            (modifiers & 32 /* Static */ ? 512 /* ContainsStatic */ : 0);
                        if (!isMethodLike(prop)) {
                            syntheticFlag = 2 /* SyntheticProperty */;
                        }
                    }
                    else if (isUnion) {
                        checkFlags |= 16 /* Partial */;
                    }
                }
            }
            if (!props) {
                return undefined;
            }
            if (props.length === 1 && !(checkFlags & 16 /* Partial */)) {
                return props[0];
            }
            var propTypes = [];
            var declarations = [];
            var commonType = undefined;
            for (var _a = 0, props_1 = props; _a < props_1.length; _a++) {
                var prop = props_1[_a];
                if (prop.declarations) {
                    ts.addRange(declarations, prop.declarations);
                }
                var type = getTypeOfSymbol(prop);
                if (!commonType) {
                    commonType = type;
                }
                else if (type !== commonType) {
                    checkFlags |= 32 /* HasNonUniformType */;
                }
                propTypes.push(type);
            }
            var result = createSymbol(4 /* Property */ | commonFlags, name);
            result.checkFlags = syntheticFlag | checkFlags;
            result.containingType = containingType;
            result.declarations = declarations;
            result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
            return result;
        }
        // Return the symbol for a given property in a union or intersection type, or undefined if the property
        // does not exist in any constituent type. Note that the returned property may only be present in some
        // constituents, in which case the isPartial flag is set when the containing type is union type. We need
        // these partial properties when identifying discriminant properties, but otherwise they are filtered out
        // and do not appear to be present in the union type.
        function getUnionOrIntersectionProperty(type, name) {
            var properties = type.propertyCache || (type.propertyCache = ts.createSymbolTable());
            var property = properties.get(name);
            if (!property) {
                property = createUnionOrIntersectionProperty(type, name);
                if (property) {
                    properties.set(name, property);
                }
            }
            return property;
        }
        function getPropertyOfUnionOrIntersectionType(type, name) {
            var property = getUnionOrIntersectionProperty(type, name);
            // We need to filter out partial properties in union types
            return property && !(ts.getCheckFlags(property) & 16 /* Partial */) ? property : undefined;
        }
        /**
         * Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
         * necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
         * Object and Function as appropriate.
         *
         * @param type a type to look up property from
         * @param name a name of property to look up in a given type
         */
        function getPropertyOfType(type, name) {
            type = getApparentType(type);
            if (type.flags & 32768 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
                if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
                    var symbol_1 = getPropertyOfObjectType(globalFunctionType, name);
                    if (symbol_1) {
                        return symbol_1;
                    }
                }
                return getPropertyOfObjectType(globalObjectType, name);
            }
            if (type.flags & 196608 /* UnionOrIntersection */) {
                return getPropertyOfUnionOrIntersectionType(type, name);
            }
            return undefined;
        }
        function getSignaturesOfStructuredType(type, kind) {
            if (type.flags & 229376 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
            }
            return ts.emptyArray;
        }
        /**
         * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
         * maps primitive types and type parameters are to their apparent types.
         */
        function getSignaturesOfType(type, kind) {
            return getSignaturesOfStructuredType(getApparentType(type), kind);
        }
        function getIndexInfoOfStructuredType(type, kind) {
            if (type.flags & 229376 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* String */ ? resolved.stringIndexInfo : resolved.numberIndexInfo;
            }
        }
        function getIndexTypeOfStructuredType(type, kind) {
            var info = getIndexInfoOfStructuredType(type, kind);
            return info && info.type;
        }
        // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexInfoOfType(type, kind) {
            return getIndexInfoOfStructuredType(getApparentType(type), kind);
        }
        // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexTypeOfType(type, kind) {
            return getIndexTypeOfStructuredType(getApparentType(type), kind);
        }
        function getImplicitIndexTypeOfType(type, kind) {
            if (isObjectTypeWithInferableIndex(type)) {
                var propTypes = [];
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        propTypes.push(getTypeOfSymbol(prop));
                    }
                }
                if (propTypes.length) {
                    return getUnionType(propTypes, /*subtypeReduction*/ true);
                }
            }
            return undefined;
        }
        // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
        // type checking functions).
        function getTypeParametersFromDeclaration(declaration) {
            var result;
            ts.forEach(ts.getEffectiveTypeParameterDeclarations(declaration), function (node) {
                var tp = getDeclaredTypeOfTypeParameter(node.symbol);
                result = ts.appendIfUnique(result, tp);
            });
            return result;
        }
        function symbolsToArray(symbols) {
            var result = [];
            symbols.forEach(function (symbol, id) {
                if (!isReservedMemberName(id)) {
                    result.push(symbol);
                }
            });
            return result;
        }
        function isJSDocOptionalParameter(node) {
            if (ts.isInJavaScriptFile(node)) {
                if (node.type && node.type.kind === 272 /* JSDocOptionalType */) {
                    return true;
                }
                var paramTags = ts.getJSDocParameterTags(node);
                if (paramTags) {
                    for (var _i = 0, paramTags_1 = paramTags; _i < paramTags_1.length; _i++) {
                        var paramTag = paramTags_1[_i];
                        if (paramTag.isBracketed) {
                            return true;
                        }
                        if (paramTag.typeExpression) {
                            return paramTag.typeExpression.type.kind === 272 /* JSDocOptionalType */;
                        }
                    }
                }
            }
        }
        function tryFindAmbientModule(moduleName, withAugmentations) {
            if (ts.isExternalModuleNameRelative(moduleName)) {
                return undefined;
            }
            var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
            // merged symbol is module declaration symbol combined with all augmentations
            return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
        }
        function isOptionalParameter(node) {
            if (ts.hasQuestionToken(node) || isJSDocOptionalParameter(node)) {
                return true;
            }
            if (node.initializer) {
                var signatureDeclaration = node.parent;
                var signature = getSignatureFromDeclaration(signatureDeclaration);
                var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
                ts.Debug.assert(parameterIndex >= 0);
                return parameterIndex >= signature.minArgumentCount;
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(node.parent);
            if (iife) {
                return !node.type &&
                    !node.dotDotDotToken &&
                    ts.indexOf(node.parent.parameters, node) >= iife.arguments.length;
            }
            return false;
        }
        function createTypePredicateFromTypePredicateNode(node) {
            var parameterName = node.parameterName;
            if (parameterName.kind === 71 /* Identifier */) {
                return {
                    kind: 1 /* Identifier */,
                    parameterName: parameterName ? parameterName.escapedText : undefined,
                    parameterIndex: parameterName ? getTypePredicateParameterIndex(node.parent.parameters, parameterName) : undefined,
                    type: getTypeFromTypeNode(node.type)
                };
            }
            else {
                return {
                    kind: 0 /* This */,
                    type: getTypeFromTypeNode(node.type)
                };
            }
        }
        /**
         * Gets the minimum number of type arguments needed to satisfy all non-optional type
         * parameters.
         */
        function getMinTypeArgumentCount(typeParameters) {
            var minTypeArgumentCount = 0;
            if (typeParameters) {
                for (var i = 0; i < typeParameters.length; i++) {
                    if (!hasTypeParameterDefault(typeParameters[i])) {
                        minTypeArgumentCount = i + 1;
                    }
                }
            }
            return minTypeArgumentCount;
        }
        /**
         * Fill in default types for unsupplied type arguments. If `typeArguments` is undefined
         * when a default type is supplied, a new array will be created and returned.
         *
         * @param typeArguments The supplied type arguments.
         * @param typeParameters The requested type parameters.
         * @param minTypeArgumentCount The minimum number of required type arguments.
         */
        function fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount, isJavaScript) {
            var numTypeParameters = ts.length(typeParameters);
            if (numTypeParameters) {
                var numTypeArguments = ts.length(typeArguments);
                if ((isJavaScript || numTypeArguments >= minTypeArgumentCount) && numTypeArguments <= numTypeParameters) {
                    if (!typeArguments) {
                        typeArguments = [];
                    }
                    // Map an unsatisfied type parameter with a default type.
                    // If a type parameter does not have a default type, or if the default type
                    // is a forward reference, the empty object type is used.
                    for (var i = numTypeArguments; i < numTypeParameters; i++) {
                        typeArguments[i] = getDefaultTypeArgumentType(isJavaScript);
                    }
                    for (var i = numTypeArguments; i < numTypeParameters; i++) {
                        var mapper = createTypeMapper(typeParameters, typeArguments);
                        var defaultType = getDefaultFromTypeParameter(typeParameters[i]);
                        typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScript);
                    }
                }
            }
            return typeArguments;
        }
        function getSignatureFromDeclaration(declaration) {
            var links = getNodeLinks(declaration);
            if (!links.resolvedSignature) {
                var parameters = [];
                var hasLiteralTypes = false;
                var minArgumentCount = 0;
                var thisParameter = undefined;
                var hasThisParameter = void 0;
                var iife = ts.getImmediatelyInvokedFunctionExpression(declaration);
                var isJSConstructSignature = ts.isJSDocConstructSignature(declaration);
                var isUntypedSignatureInJSFile = !iife && !isJSConstructSignature && ts.isInJavaScriptFile(declaration) && !ts.hasJSDocParameterTags(declaration);
                // If this is a JSDoc construct signature, then skip the first parameter in the
                // parameter list.  The first parameter represents the return type of the construct
                // signature.
                for (var i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) {
                    var param = declaration.parameters[i];
                    var paramSymbol = param.symbol;
                    // Include parameter symbol instead of property symbol in the signature
                    if (paramSymbol && !!(paramSymbol.flags & 4 /* Property */) && !ts.isBindingPattern(param.name)) {
                        var resolvedSymbol = resolveName(param, paramSymbol.escapedName, 107455 /* Value */, undefined, undefined, /*isUse*/ false);
                        paramSymbol = resolvedSymbol;
                    }
                    if (i === 0 && paramSymbol.escapedName === "this") {
                        hasThisParameter = true;
                        thisParameter = param.symbol;
                    }
                    else {
                        parameters.push(paramSymbol);
                    }
                    if (param.type && param.type.kind === 173 /* LiteralType */) {
                        hasLiteralTypes = true;
                    }
                    // Record a new minimum argument count if this is not an optional parameter
                    var isOptionalParameter_1 = param.initializer || param.questionToken || param.dotDotDotToken ||
                        iife && parameters.length > iife.arguments.length && !param.type ||
                        isJSDocOptionalParameter(param) ||
                        isUntypedSignatureInJSFile;
                    if (!isOptionalParameter_1) {
                        minArgumentCount = parameters.length;
                    }
                }
                // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
                if ((declaration.kind === 153 /* GetAccessor */ || declaration.kind === 154 /* SetAccessor */) &&
                    !ts.hasDynamicName(declaration) &&
                    (!hasThisParameter || !thisParameter)) {
                    var otherKind = declaration.kind === 153 /* GetAccessor */ ? 154 /* SetAccessor */ : 153 /* GetAccessor */;
                    var other = ts.getDeclarationOfKind(declaration.symbol, otherKind);
                    if (other) {
                        thisParameter = getAnnotatedAccessorThisParameter(other);
                    }
                }
                var classType = declaration.kind === 152 /* Constructor */ ?
                    getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol))
                    : undefined;
                var typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
                var returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
                var typePredicate = declaration.type && declaration.type.kind === 158 /* TypePredicate */ ?
                    createTypePredicateFromTypePredicateNode(declaration.type) :
                    undefined;
                // JS functions get a free rest parameter if they reference `arguments`
                var hasRestLikeParameter = ts.hasRestParameter(declaration);
                if (!hasRestLikeParameter && ts.isInJavaScriptFile(declaration) && containsArgumentsReference(declaration)) {
                    hasRestLikeParameter = true;
                    var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args");
                    syntheticArgsSymbol.type = anyArrayType;
                    syntheticArgsSymbol.isRestParameter = true;
                    parameters.push(syntheticArgsSymbol);
                }
                links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
            }
            return links.resolvedSignature;
        }
        function getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType) {
            if (isJSConstructSignature) {
                return getTypeFromTypeNode(declaration.parameters[0].type);
            }
            else if (classType) {
                return classType;
            }
            var typeNode = ts.getEffectiveReturnTypeNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            // TypeScript 1.0 spec (April 2014):
            // If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
            if (declaration.kind === 153 /* GetAccessor */ && !ts.hasDynamicName(declaration)) {
                var setter = ts.getDeclarationOfKind(declaration.symbol, 154 /* SetAccessor */);
                return getAnnotatedAccessorType(setter);
            }
            if (ts.nodeIsMissing(declaration.body)) {
                return anyType;
            }
        }
        function containsArgumentsReference(declaration) {
            var links = getNodeLinks(declaration);
            if (links.containsArgumentsReference === undefined) {
                if (links.flags & 8192 /* CaptureArguments */) {
                    links.containsArgumentsReference = true;
                }
                else {
                    links.containsArgumentsReference = traverse(declaration.body);
                }
            }
            return links.containsArgumentsReference;
            function traverse(node) {
                if (!node)
                    return false;
                switch (node.kind) {
                    case 71 /* Identifier */:
                        return node.escapedText === "arguments" && ts.isPartOfExpression(node);
                    case 149 /* PropertyDeclaration */:
                    case 151 /* MethodDeclaration */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        return node.name.kind === 144 /* ComputedPropertyName */
                            && traverse(node.name);
                    default:
                        return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && ts.forEachChild(node, traverse);
                }
            }
        }
        function getSignaturesOfSymbol(symbol) {
            if (!symbol)
                return ts.emptyArray;
            var result = [];
            for (var i = 0; i < symbol.declarations.length; i++) {
                var node = symbol.declarations[i];
                switch (node.kind) {
                    case 160 /* FunctionType */:
                    case 161 /* ConstructorType */:
                    case 228 /* FunctionDeclaration */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                    case 152 /* Constructor */:
                    case 155 /* CallSignature */:
                    case 156 /* ConstructSignature */:
                    case 157 /* IndexSignature */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    case 186 /* FunctionExpression */:
                    case 187 /* ArrowFunction */:
                    case 273 /* JSDocFunctionType */:
                        // Don't include signature if node is the implementation of an overloaded function. A node is considered
                        // an implementation node if it has a body and the previous node is of the same kind and immediately
                        // precedes the implementation node (i.e. has the same parent and ends where the implementation starts).
                        if (i > 0 && node.body) {
                            var previous = symbol.declarations[i - 1];
                            if (node.parent === previous.parent && node.kind === previous.kind && node.pos === previous.end) {
                                break;
                            }
                        }
                        result.push(getSignatureFromDeclaration(node));
                }
            }
            return result;
        }
        function resolveExternalModuleTypeByLiteral(name) {
            var moduleSym = resolveExternalModuleName(name, name);
            if (moduleSym) {
                var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                if (resolvedModuleSymbol) {
                    return getTypeOfSymbol(resolvedModuleSymbol);
                }
            }
            return anyType;
        }
        function getThisTypeOfSignature(signature) {
            if (signature.thisParameter) {
                return getTypeOfSymbol(signature.thisParameter);
            }
        }
        function getReturnTypeOfSignature(signature) {
            if (!signature.resolvedReturnType) {
                if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
                    return unknownType;
                }
                var type = void 0;
                if (signature.target) {
                    type = instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper);
                }
                else if (signature.unionSignatures) {
                    type = getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
                }
                else {
                    type = getReturnTypeFromBody(signature.declaration);
                }
                if (!popTypeResolution()) {
                    type = anyType;
                    if (noImplicitAny) {
                        var declaration = signature.declaration;
                        var name = ts.getNameOfDeclaration(declaration);
                        if (name) {
                            error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name));
                        }
                        else {
                            error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions);
                        }
                    }
                }
                signature.resolvedReturnType = type;
            }
            return signature.resolvedReturnType;
        }
        function isResolvingReturnTypeOfSignature(signature) {
            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
        }
        function getRestTypeOfSignature(signature) {
            if (signature.hasRestParameter) {
                var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
                if (getObjectFlags(type) & 4 /* Reference */ && type.target === globalArrayType) {
                    return type.typeArguments[0];
                }
            }
            return anyType;
        }
        function getSignatureInstantiation(signature, typeArguments, isJavascript) {
            typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript);
            var instantiations = signature.instantiations || (signature.instantiations = ts.createMap());
            var id = getTypeListId(typeArguments);
            var instantiation = instantiations.get(id);
            if (!instantiation) {
                instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments));
            }
            return instantiation;
        }
        function createSignatureInstantiation(signature, typeArguments) {
            return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
        }
        function getErasedSignature(signature) {
            return signature.typeParameters ?
                signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
                signature;
        }
        function createErasedSignature(signature) {
            // Create an instantiation of the signature where all type arguments are the any type.
            return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
        }
        function getCanonicalSignature(signature) {
            return signature.typeParameters ?
                signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
                signature;
        }
        function createCanonicalSignature(signature) {
            // Create an instantiation of the signature where each unconstrained type parameter is replaced with
            // its original. When a generic class or interface is instantiated, each generic method in the class or
            // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
            // where different generations of the same type parameter are in scope). This leads to a lot of new type
            // identities, and potentially a lot of work comparing those identities, so here we create an instantiation
            // that uses the original type identities for all unconstrained type parameters.
            return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; }), ts.isInJavaScriptFile(signature.declaration));
        }
        function getOrCreateTypeFromSignature(signature) {
            // There are two ways to declare a construct signature, one is by declaring a class constructor
            // using the constructor keyword, and the other is declaring a bare construct signature in an
            // object type literal or interface (using the new keyword). Each way of declaring a constructor
            // will result in a different declaration kind.
            if (!signature.isolatedSignatureType) {
                var isConstructor = signature.declaration.kind === 152 /* Constructor */ || signature.declaration.kind === 156 /* ConstructSignature */;
                var type = createObjectType(16 /* Anonymous */);
                type.members = emptySymbols;
                type.properties = ts.emptyArray;
                type.callSignatures = !isConstructor ? [signature] : ts.emptyArray;
                type.constructSignatures = isConstructor ? [signature] : ts.emptyArray;
                signature.isolatedSignatureType = type;
            }
            return signature.isolatedSignatureType;
        }
        function getIndexSymbol(symbol) {
            return symbol.members.get("__index" /* Index */);
        }
        function getIndexDeclarationOfSymbol(symbol, kind) {
            var syntaxKind = kind === 1 /* Number */ ? 133 /* NumberKeyword */ : 136 /* StringKeyword */;
            var indexSymbol = getIndexSymbol(symbol);
            if (indexSymbol) {
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var node = decl;
                    if (node.parameters.length === 1) {
                        var parameter = node.parameters[0];
                        if (parameter && parameter.type && parameter.type.kind === syntaxKind) {
                            return node;
                        }
                    }
                }
            }
            return undefined;
        }
        function createIndexInfo(type, isReadonly, declaration) {
            return { type: type, isReadonly: isReadonly, declaration: declaration };
        }
        function getIndexInfoOfSymbol(symbol, kind) {
            var declaration = getIndexDeclarationOfSymbol(symbol, kind);
            if (declaration) {
                return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration);
            }
            return undefined;
        }
        function getConstraintDeclaration(type) {
            return type.symbol && ts.getDeclarationOfKind(type.symbol, 145 /* TypeParameter */).constraint;
        }
        function getConstraintFromTypeParameter(typeParameter) {
            if (!typeParameter.constraint) {
                if (typeParameter.target) {
                    var targetConstraint = getConstraintOfTypeParameter(typeParameter.target);
                    typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType;
                }
                else {
                    var constraintDeclaration = getConstraintDeclaration(typeParameter);
                    typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) : noConstraintType;
                }
            }
            return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;
        }
        function getParentSymbolOfTypeParameter(typeParameter) {
            return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 145 /* TypeParameter */).parent);
        }
        function getTypeListId(types) {
            var result = "";
            if (types) {
                var length_4 = types.length;
                var i = 0;
                while (i < length_4) {
                    var startId = types[i].id;
                    var count = 1;
                    while (i + count < length_4 && types[i + count].id === startId + count) {
                        count++;
                    }
                    if (result.length) {
                        result += ",";
                    }
                    result += startId;
                    if (count > 1) {
                        result += ":" + count;
                    }
                    i += count;
                }
            }
            return result;
        }
        // This function is used to propagate certain flags when creating new object type references and union types.
        // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
        // of an object literal or the anyFunctionType. This is because there are operations in the type checker
        // that care about the presence of such types at arbitrary depth in a containing type.
        function getPropagatingFlagsOfTypes(types, excludeKinds) {
            var result = 0;
            for (var _i = 0, types_5 = types; _i < types_5.length; _i++) {
                var type = types_5[_i];
                if (!(type.flags & excludeKinds)) {
                    result |= type.flags;
                }
            }
            return result & 14680064 /* PropagatingFlags */;
        }
        function createTypeReference(target, typeArguments) {
            var id = getTypeListId(typeArguments);
            var type = target.instantiations.get(id);
            if (!type) {
                type = createObjectType(4 /* Reference */, target.symbol);
                target.instantiations.set(id, type);
                type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
                type.target = target;
                type.typeArguments = typeArguments;
            }
            return type;
        }
        function cloneTypeReference(source) {
            var type = createType(source.flags);
            type.symbol = source.symbol;
            type.objectFlags = source.objectFlags;
            type.target = source.target;
            type.typeArguments = source.typeArguments;
            return type;
        }
        function getTypeReferenceArity(type) {
            return ts.length(type.target.typeParameters);
        }
        /**
         * Get type from type-reference that reference to class or interface
         */
        function getTypeFromClassOrInterfaceReference(node, symbol, typeArgs) {
            var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
            var typeParameters = type.localTypeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                var isJavascript = ts.isInJavaScriptFile(node);
                if (!isJavascript && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
                    error(node, minTypeArgumentCount === typeParameters.length
                        ? ts.Diagnostics.Generic_type_0_requires_1_type_argument_s
                        : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */), minTypeArgumentCount, typeParameters.length);
                    return unknownType;
                }
                // In a type reference, the outer type parameters of the referenced class or interface are automatically
                // supplied as type arguments and the type reference only specifies arguments for the local type parameters
                // of the class or interface.
                var typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJavascript));
                return createTypeReference(type, typeArguments);
            }
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
                return unknownType;
            }
            return type;
        }
        function getTypeAliasInstantiation(symbol, typeArguments) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            var id = getTypeListId(typeArguments);
            var instantiation = links.instantiations.get(id);
            if (!instantiation) {
                links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJavaScriptFile(symbol.valueDeclaration)))));
            }
            return instantiation;
        }
        /**
         * Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
         * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
         * declared type. Instantiations are cached using the type identities of the type arguments as the key.
         */
        function getTypeFromTypeAliasReference(node, symbol, typeArguments) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeParameters = getSymbolLinks(symbol).typeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) {
                    error(node, minTypeArgumentCount === typeParameters.length
                        ? ts.Diagnostics.Generic_type_0_requires_1_type_argument_s
                        : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length);
                    return unknownType;
                }
                return getTypeAliasInstantiation(symbol, typeArguments);
            }
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
                return unknownType;
            }
            return type;
        }
        function getTypeReferenceName(node) {
            switch (node.kind) {
                case 159 /* TypeReference */:
                    return node.typeName;
                case 201 /* ExpressionWithTypeArguments */:
                    // We only support expressions that are simple qualified names. For other
                    // expressions this produces undefined.
                    var expr = node.expression;
                    if (ts.isEntityNameExpression(expr)) {
                        return expr;
                    }
            }
            return undefined;
        }
        function resolveTypeReferenceName(typeReferenceName, meaning) {
            if (!typeReferenceName) {
                return unknownSymbol;
            }
            return resolveEntityName(typeReferenceName, meaning) || unknownSymbol;
        }
        function getTypeReferenceType(node, symbol) {
            var typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
            if (symbol === unknownSymbol) {
                return unknownType;
            }
            var type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
            if (type) {
                return type;
            }
            // Get type from reference to named type that cannot be generic (enum or type parameter)
            var res = tryGetDeclaredTypeOfSymbol(symbol);
            if (res !== undefined) {
                if (typeArguments) {
                    error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
                    return unknownType;
                }
                return res;
            }
            if (!(symbol.flags & 107455 /* Value */ && isJSDocTypeReference(node))) {
                return unknownType;
            }
            // A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
            // the symbol is a constructor function, return the inferred class type; otherwise,
            // the type of this reference is just the type of the value we resolved to.
            var valueType = getTypeOfSymbol(symbol);
            if (valueType.symbol && !isInferredClassType(valueType)) {
                var referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
                if (referenceType) {
                    return referenceType;
                }
            }
            // Resolve the type reference as a Type for the purpose of reporting errors.
            resolveTypeReferenceName(getTypeReferenceName(node), 793064 /* Type */);
            return valueType;
        }
        function getTypeReferenceTypeWorker(node, symbol, typeArguments) {
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getTypeFromTypeAliasReference(node, symbol, typeArguments);
            }
            if (symbol.flags & 16 /* Function */ &&
                isJSDocTypeReference(node) &&
                (symbol.members || ts.getJSDocClassTag(symbol.valueDeclaration))) {
                return getInferredClassType(symbol);
            }
        }
        function isJSDocTypeReference(node) {
            return node.flags & 1048576 /* JSDoc */ && node.kind === 159 /* TypeReference */;
        }
        function getIntendedTypeFromJSDocTypeReference(node) {
            if (ts.isIdentifier(node.typeName)) {
                if (node.typeName.escapedText === "Object") {
                    if (ts.isJSDocIndexSignature(node)) {
                        var indexed = getTypeFromTypeNode(node.typeArguments[0]);
                        var target = getTypeFromTypeNode(node.typeArguments[1]);
                        var index = createIndexInfo(target, /*isReadonly*/ false);
                        return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexed === stringType && index, indexed === numberType && index);
                    }
                    return anyType;
                }
                switch (node.typeName.escapedText) {
                    case "String":
                        return stringType;
                    case "Number":
                        return numberType;
                    case "Boolean":
                        return booleanType;
                    case "Void":
                        return voidType;
                    case "Undefined":
                        return undefinedType;
                    case "Null":
                        return nullType;
                    case "Function":
                    case "function":
                        return globalFunctionType;
                    case "Array":
                    case "array":
                        return !node.typeArguments || !node.typeArguments.length ? anyArrayType : undefined;
                    case "Promise":
                    case "promise":
                        return !node.typeArguments || !node.typeArguments.length ? createPromiseType(anyType) : undefined;
                }
            }
        }
        function getTypeFromJSDocNullableTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getUnionType([type, nullType]) : type;
        }
        function getTypeFromTypeReference(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var symbol = void 0;
                var type = void 0;
                var meaning = 793064 /* Type */;
                if (isJSDocTypeReference(node)) {
                    type = getIntendedTypeFromJSDocTypeReference(node);
                    meaning |= 107455 /* Value */;
                }
                if (!type) {
                    symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
                    type = getTypeReferenceType(node, symbol);
                }
                // Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
                // type reference in checkTypeReferenceOrExpressionWithTypeArguments.
                links.resolvedSymbol = symbol;
                links.resolvedType = type;
            }
            return links.resolvedType;
        }
        function typeArgumentsFromTypeReferenceNode(node) {
            return ts.map(node.typeArguments, getTypeFromTypeNode);
        }
        function getTypeFromTypeQueryNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // TypeScript 1.0 spec (April 2014): 3.6.3
                // The expression is processed as an identifier expression (section 4.3)
                // or property access expression(section 4.10),
                // the widened type(section 3.9) of which becomes the result.
                links.resolvedType = getWidenedType(checkExpression(node.exprName));
            }
            return links.resolvedType;
        }
        function getTypeOfGlobalSymbol(symbol, arity) {
            function getTypeDeclaration(symbol) {
                var declarations = symbol.declarations;
                for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
                    var declaration = declarations_3[_i];
                    switch (declaration.kind) {
                        case 229 /* ClassDeclaration */:
                        case 230 /* InterfaceDeclaration */:
                        case 232 /* EnumDeclaration */:
                            return declaration;
                    }
                }
            }
            if (!symbol) {
                return arity ? emptyGenericType : emptyObjectType;
            }
            var type = getDeclaredTypeOfSymbol(symbol);
            if (!(type.flags & 32768 /* Object */)) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol));
                return arity ? emptyGenericType : emptyObjectType;
            }
            if (ts.length(type.typeParameters) !== arity) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity);
                return arity ? emptyGenericType : emptyObjectType;
            }
            return type;
        }
        function getGlobalValueSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 107455 /* Value */, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined);
        }
        function getGlobalTypeSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 793064 /* Type */, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined);
        }
        function getGlobalSymbol(name, meaning, diagnostic) {
            // Don't track references for global symbols anyway, so value if `isReference` is arbitrary
            return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false);
        }
        function getGlobalType(name, arity, reportErrors) {
            var symbol = getGlobalTypeSymbol(name, reportErrors);
            return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined;
        }
        function getGlobalTypedPropertyDescriptorType() {
            return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor", /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType;
        }
        function getGlobalTemplateStringsArrayType() {
            return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalESSymbolConstructorSymbol(reportErrors) {
            return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol", reportErrors));
        }
        function getGlobalESSymbolType(reportErrors) {
            return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalPromiseType(reportErrors) {
            return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseConstructorSymbol(reportErrors) {
            return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise", reportErrors));
        }
        function getGlobalPromiseConstructorLikeType(reportErrors) {
            return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalAsyncIterableType(reportErrors) {
            return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIteratorType(reportErrors) {
            return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIterableIteratorType(reportErrors) {
            return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableType(reportErrors) {
            return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorType(reportErrors) {
            return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableIteratorType(reportErrors) {
            return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalTypeOrUndefined(name, arity) {
            if (arity === void 0) { arity = 0; }
            var symbol = getGlobalSymbol(name, 793064 /* Type */, /*diagnostic*/ undefined);
            return symbol && getTypeOfGlobalSymbol(symbol, arity);
        }
        /**
         * Returns a type that is inside a namespace at the global scope, e.g.
         * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type
         */
        function getExportedTypeFromNamespace(namespace, name) {
            var namespaceSymbol = getGlobalSymbol(namespace, 1920 /* Namespace */, /*diagnosticMessage*/ undefined);
            var typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, 793064 /* Type */);
            return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol);
        }
        /**
         * Instantiates a global type that is generic with some element type, and returns that instantiation.
         */
        function createTypeFromGenericGlobalType(genericGlobalType, typeArguments) {
            return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType;
        }
        function createTypedPropertyDescriptorType(propertyType) {
            return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
        }
        function createAsyncIterableType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalAsyncIterableType(/*reportErrors*/ true), [iteratedType]);
        }
        function createAsyncIterableIteratorType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalAsyncIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
        }
        function createIterableType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
        }
        function createIterableIteratorType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
        }
        function createArrayType(elementType) {
            return createTypeFromGenericGlobalType(globalArrayType, [elementType]);
        }
        function getTypeFromArrayTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType));
            }
            return links.resolvedType;
        }
        // We represent tuple types as type references to synthesized generic interface types created by
        // this function. The types are of the form:
        //
        //   interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }
        //
        // Note that the generic type created by this function has no symbol associated with it. The same
        // is true for each of the synthesized type parameters.
        function createTupleTypeOfArity(arity) {
            var typeParameters = [];
            var properties = [];
            for (var i = 0; i < arity; i++) {
                var typeParameter = createType(16384 /* TypeParameter */);
                typeParameters.push(typeParameter);
                var property = createSymbol(4 /* Property */, "" + i);
                property.type = typeParameter;
                properties.push(property);
            }
            var type = createObjectType(8 /* Tuple */ | 4 /* Reference */);
            type.typeParameters = typeParameters;
            type.outerTypeParameters = undefined;
            type.localTypeParameters = typeParameters;
            type.instantiations = ts.createMap();
            type.instantiations.set(getTypeListId(type.typeParameters), type);
            type.target = type;
            type.typeArguments = type.typeParameters;
            type.thisType = createType(16384 /* TypeParameter */);
            type.thisType.isThisType = true;
            type.thisType.constraint = type;
            type.declaredProperties = properties;
            type.declaredCallSignatures = ts.emptyArray;
            type.declaredConstructSignatures = ts.emptyArray;
            type.declaredStringIndexInfo = undefined;
            type.declaredNumberIndexInfo = undefined;
            return type;
        }
        function getTupleTypeOfArity(arity) {
            return tupleTypes[arity] || (tupleTypes[arity] = createTupleTypeOfArity(arity));
        }
        function createTupleType(elementTypes) {
            return createTypeReference(getTupleTypeOfArity(elementTypes.length), elementTypes);
        }
        function getTypeFromTupleTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = createTupleType(ts.map(node.elementTypes, getTypeFromTypeNode));
            }
            return links.resolvedType;
        }
        function binarySearchTypes(types, type) {
            var low = 0;
            var high = types.length - 1;
            var typeId = type.id;
            while (low <= high) {
                var middle = low + ((high - low) >> 1);
                var id = types[middle].id;
                if (id === typeId) {
                    return middle;
                }
                else if (id > typeId) {
                    high = middle - 1;
                }
                else {
                    low = middle + 1;
                }
            }
            return ~low;
        }
        function containsType(types, type) {
            return binarySearchTypes(types, type) >= 0;
        }
        // Return true if the given intersection type contains (a) more than one unit type or (b) an object
        // type and a nullable type (null or undefined).
        function isEmptyIntersectionType(type) {
            var combined = 0;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (t.flags & 6368 /* Unit */ && combined & 6368 /* Unit */) {
                    return true;
                }
                combined |= t.flags;
                if (combined & 6144 /* Nullable */ && combined & (32768 /* Object */ | 16777216 /* NonPrimitive */)) {
                    return true;
                }
            }
            return false;
        }
        function addTypeToUnion(typeSet, type) {
            var flags = type.flags;
            if (flags & 65536 /* Union */) {
                addTypesToUnion(typeSet, type.types);
            }
            else if (flags & 1 /* Any */) {
                typeSet.containsAny = true;
            }
            else if (!strictNullChecks && flags & 6144 /* Nullable */) {
                if (flags & 2048 /* Undefined */)
                    typeSet.containsUndefined = true;
                if (flags & 4096 /* Null */)
                    typeSet.containsNull = true;
                if (!(flags & 2097152 /* ContainsWideningType */))
                    typeSet.containsNonWideningType = true;
            }
            else if (!(flags & 8192 /* Never */ || flags & 131072 /* Intersection */ && isEmptyIntersectionType(type))) {
                // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
                // another form of 'never' (in that they have an empty value domain). We could in theory turn
                // intersections of unit types into 'never' upon construction, but deferring the reduction makes it
                // easier to reason about their origin.
                if (flags & 2 /* String */)
                    typeSet.containsString = true;
                if (flags & 4 /* Number */)
                    typeSet.containsNumber = true;
                if (flags & 96 /* StringOrNumberLiteral */)
                    typeSet.containsStringOrNumberLiteral = true;
                var len = typeSet.length;
                var index = len && type.id > typeSet[len - 1].id ? ~len : binarySearchTypes(typeSet, type);
                if (index < 0) {
                    if (!(flags & 32768 /* Object */ && type.objectFlags & 16 /* Anonymous */ &&
                        type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */) && containsIdenticalType(typeSet, type))) {
                        typeSet.splice(~index, 0, type);
                    }
                }
            }
        }
        // Add the given types to the given type set. Order is preserved, duplicates are removed,
        // and nested types of the given kind are flattened into the set.
        function addTypesToUnion(typeSet, types) {
            for (var _i = 0, types_6 = types; _i < types_6.length; _i++) {
                var type = types_6[_i];
                addTypeToUnion(typeSet, type);
            }
        }
        function containsIdenticalType(types, type) {
            for (var _i = 0, types_7 = types; _i < types_7.length; _i++) {
                var t = types_7[_i];
                if (isTypeIdenticalTo(t, type)) {
                    return true;
                }
            }
            return false;
        }
        function isSubtypeOfAny(candidate, types) {
            for (var _i = 0, types_8 = types; _i < types_8.length; _i++) {
                var type = types_8[_i];
                if (candidate !== type && isTypeSubtypeOf(candidate, type)) {
                    return true;
                }
            }
            return false;
        }
        function isSetOfLiteralsFromSameEnum(types) {
            var first = types[0];
            if (first.flags & 256 /* EnumLiteral */) {
                var firstEnum = getParentOfSymbol(first.symbol);
                for (var i = 1; i < types.length; i++) {
                    var other = types[i];
                    if (!(other.flags & 256 /* EnumLiteral */) || (firstEnum !== getParentOfSymbol(other.symbol))) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
        function removeSubtypes(types) {
            if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) {
                return;
            }
            var i = types.length;
            while (i > 0) {
                i--;
                if (isSubtypeOfAny(types[i], types)) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        function removeRedundantLiteralTypes(types) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 32 /* StringLiteral */ && types.containsString ||
                    t.flags & 64 /* NumberLiteral */ && types.containsNumber ||
                    t.flags & 96 /* StringOrNumberLiteral */ && t.flags & 1048576 /* FreshLiteral */ && containsType(types, t.regularType);
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
        // flag is specified we also reduce the constituent type set to only include types that aren't subtypes
        // of other types. Subtype reduction is expensive for large union types and is possible only when union
        // types are known not to circularly reference themselves (as is the case with union types created by
        // expression constructs such as array literals and the || and ?: operators). Named types can
        // circularly reference themselves and therefore cannot be subtype reduced during their declaration.
        // For example, "type Item = string | (() => Item" is a named type that circularly references itself.
        function getUnionType(types, subtypeReduction, aliasSymbol, aliasTypeArguments) {
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var typeSet = [];
            addTypesToUnion(typeSet, types);
            if (typeSet.containsAny) {
                return anyType;
            }
            if (subtypeReduction) {
                removeSubtypes(typeSet);
            }
            else if (typeSet.containsStringOrNumberLiteral) {
                removeRedundantLiteralTypes(typeSet);
            }
            if (typeSet.length === 0) {
                return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType :
                    typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType :
                        neverType;
            }
            return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
        }
        // This function assumes the constituent type list is sorted and deduplicated.
        function getUnionTypeFromSortedList(types, aliasSymbol, aliasTypeArguments) {
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var id = getTypeListId(types);
            var type = unionTypes.get(id);
            if (!type) {
                var propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 6144 /* Nullable */);
                type = createType(65536 /* Union */ | propagatedFlags);
                unionTypes.set(id, type);
                type.types = types;
                /*
                Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
                For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
                (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
                It's important that we create equivalent union types only once, so that's an unfortunate side effect.
                */
                type.aliasSymbol = aliasSymbol;
                type.aliasTypeArguments = aliasTypeArguments;
            }
            return type;
        }
        function getTypeFromUnionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*subtypeReduction*/ false, getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
            }
            return links.resolvedType;
        }
        function addTypeToIntersection(typeSet, type) {
            if (type.flags & 131072 /* Intersection */) {
                addTypesToIntersection(typeSet, type.types);
            }
            else if (type.flags & 1 /* Any */) {
                typeSet.containsAny = true;
            }
            else if (type.flags & 8192 /* Never */) {
                typeSet.containsNever = true;
            }
            else if (getObjectFlags(type) & 16 /* Anonymous */ && isEmptyObjectType(type)) {
                typeSet.containsEmptyObject = true;
            }
            else if ((strictNullChecks || !(type.flags & 6144 /* Nullable */)) && !ts.contains(typeSet, type)) {
                if (type.flags & 32768 /* Object */) {
                    typeSet.containsObjectType = true;
                }
                if (type.flags & 65536 /* Union */ && typeSet.unionIndex === undefined) {
                    typeSet.unionIndex = typeSet.length;
                }
                if (!(type.flags & 32768 /* Object */ && type.objectFlags & 16 /* Anonymous */ &&
                    type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */) && containsIdenticalType(typeSet, type))) {
                    typeSet.push(type);
                }
            }
        }
        // Add the given types to the given type set. Order is preserved, duplicates are removed,
        // and nested types of the given kind are flattened into the set.
        function addTypesToIntersection(typeSet, types) {
            for (var _i = 0, types_9 = types; _i < types_9.length; _i++) {
                var type = types_9[_i];
                addTypeToIntersection(typeSet, type);
            }
        }
        // We normalize combinations of intersection and union types based on the distributive property of the '&'
        // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
        // types with union type constituents into equivalent union types with intersection type constituents and
        // effectively ensure that union types are always at the top level in type representations.
        //
        // We do not perform structural deduplication on intersection types. Intersection types are created only by the &
        // type operator and we can't reduce those because we want to support recursive intersection types. For example,
        // a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
        // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
        // for intersections of types with signatures can be deterministic.
        function getIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            if (types.length === 0) {
                return emptyObjectType;
            }
            var typeSet = [];
            addTypesToIntersection(typeSet, types);
            if (typeSet.containsNever) {
                return neverType;
            }
            if (typeSet.containsAny) {
                return anyType;
            }
            if (typeSet.containsEmptyObject && !typeSet.containsObjectType) {
                typeSet.push(emptyObjectType);
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var unionIndex = typeSet.unionIndex;
            if (unionIndex !== undefined) {
                // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
                // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
                var unionType = typeSet[unionIndex];
                return getUnionType(ts.map(unionType.types, function (t) { return getIntersectionType(ts.replaceElement(typeSet, unionIndex, t)); }), 
                /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
            }
            var id = getTypeListId(typeSet);
            var type = intersectionTypes.get(id);
            if (!type) {
                var propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ 6144 /* Nullable */);
                type = createType(131072 /* Intersection */ | propagatedFlags);
                intersectionTypes.set(id, type);
                type.types = typeSet;
                type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
                type.aliasTypeArguments = aliasTypeArguments;
            }
            return type;
        }
        function getTypeFromIntersectionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
            }
            return links.resolvedType;
        }
        function getIndexTypeForGenericType(type) {
            if (!type.resolvedIndexType) {
                type.resolvedIndexType = createType(262144 /* Index */);
                type.resolvedIndexType.type = type;
            }
            return type.resolvedIndexType;
        }
        function getLiteralTypeFromPropertyName(prop) {
            return ts.getDeclarationModifierFlagsFromSymbol(prop) & 24 /* NonPublicAccessibilityModifier */ || ts.startsWith(prop.escapedName, "__@") ?
                neverType :
                getLiteralType(ts.symbolName(prop));
        }
        function getLiteralTypeFromPropertyNames(type) {
            return getUnionType(ts.map(getPropertiesOfType(type), getLiteralTypeFromPropertyName));
        }
        function getIndexType(type) {
            return maybeTypeOfKind(type, 540672 /* TypeVariable */) ? getIndexTypeForGenericType(type) :
                getObjectFlags(type) & 32 /* Mapped */ ? getConstraintTypeFromMappedType(type) :
                    type.flags & 1 /* Any */ || getIndexInfoOfType(type, 0 /* String */) ? stringType :
                        getLiteralTypeFromPropertyNames(type);
        }
        function getIndexTypeOrString(type) {
            var indexType = getIndexType(type);
            return indexType !== neverType ? indexType : stringType;
        }
        function getTypeFromTypeOperatorNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
            }
            return links.resolvedType;
        }
        function createIndexedAccessType(objectType, indexType) {
            var type = createType(524288 /* IndexedAccess */);
            type.objectType = objectType;
            type.indexType = indexType;
            return type;
        }
        function getPropertyTypeForIndexType(objectType, indexType, accessNode, cacheSymbol) {
            var accessExpression = accessNode && accessNode.kind === 180 /* ElementAccessExpression */ ? accessNode : undefined;
            var propName = indexType.flags & 96 /* StringOrNumberLiteral */ ?
                ts.escapeLeadingUnderscores("" + indexType.value) :
                accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
                    ts.getPropertyNameForKnownSymbolName(ts.idText(accessExpression.argumentExpression.name)) :
                    undefined;
            if (propName !== undefined) {
                var prop = getPropertyOfType(objectType, propName);
                if (prop) {
                    if (accessExpression) {
                        if (ts.isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop));
                            return unknownType;
                        }
                        if (cacheSymbol) {
                            getNodeLinks(accessNode).resolvedSymbol = prop;
                        }
                    }
                    return getTypeOfSymbol(prop);
                }
            }
            if (!(indexType.flags & 6144 /* Nullable */) && isTypeAssignableToKind(indexType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */)) {
                if (isTypeAny(objectType)) {
                    return anyType;
                }
                var indexInfo = isTypeAssignableToKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) ||
                    getIndexInfoOfType(objectType, 0 /* String */) ||
                    undefined;
                if (indexInfo) {
                    if (accessExpression && indexInfo.isReadonly && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) {
                        error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                    }
                    return indexInfo.type;
                }
                if (accessExpression && !isConstEnumObjectType(objectType)) {
                    if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
                        if (getIndexTypeOfType(objectType, 1 /* Number */)) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
                        }
                        else {
                            error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType));
                        }
                    }
                    return anyType;
                }
            }
            if (accessNode) {
                var indexNode = accessNode.kind === 180 /* ElementAccessExpression */ ? accessNode.argumentExpression : accessNode.indexType;
                if (indexType.flags & (32 /* StringLiteral */ | 64 /* NumberLiteral */)) {
                    error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + indexType.value, typeToString(objectType));
                }
                else if (indexType.flags & (2 /* String */ | 4 /* Number */)) {
                    error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
                }
                else {
                    error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                }
                return unknownType;
            }
            return anyType;
        }
        function isGenericObjectType(type) {
            return type.flags & 540672 /* TypeVariable */ ? true :
                getObjectFlags(type) & 32 /* Mapped */ ? isGenericIndexType(getConstraintTypeFromMappedType(type)) :
                    type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericObjectType) :
                        false;
        }
        function isGenericIndexType(type) {
            return type.flags & (540672 /* TypeVariable */ | 262144 /* Index */) ? true :
                type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericIndexType) :
                    false;
        }
        // Return true if the given type is a non-generic object type with a string index signature and no
        // other members.
        function isStringIndexOnlyType(type) {
            if (type.flags & 32768 /* Object */ && !isGenericMappedType(type)) {
                var t = resolveStructuredTypeMembers(type);
                return t.properties.length === 0 &&
                    t.callSignatures.length === 0 && t.constructSignatures.length === 0 &&
                    t.stringIndexInfo && !t.numberIndexInfo;
            }
            return false;
        }
        // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return
        // undefined if no transformation is possible.
        function getTransformedIndexedAccessType(type) {
            var objectType = type.objectType;
            // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or
            // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a
            // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed
            // access types with default property values as expressed by D.
            if (objectType.flags & 131072 /* Intersection */ && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) {
                var regularTypes = [];
                var stringIndexTypes = [];
                for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isStringIndexOnlyType(t)) {
                        stringIndexTypes.push(getIndexTypeOfType(t, 0 /* String */));
                    }
                    else {
                        regularTypes.push(t);
                    }
                }
                return getUnionType([
                    getIndexedAccessType(getIntersectionType(regularTypes), type.indexType),
                    getIntersectionType(stringIndexTypes)
                ]);
            }
            // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
            // that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
            // construct the type Box<T[X]>.
            if (isGenericMappedType(objectType)) {
                var mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]);
                var objectTypeMapper = objectType.mapper;
                var templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper;
                return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
            }
            return undefined;
        }
        function getIndexedAccessType(objectType, indexType, accessNode) {
            // If the index type is generic, or if the object type is generic and doesn't originate in an expression,
            // we are performing a higher-order index access where we cannot meaningfully access the properties of the
            // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in
            // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
            // has always been resolved eagerly using the constraint type of 'this' at the given location.
            if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180 /* ElementAccessExpression */) && isGenericObjectType(objectType)) {
                if (objectType.flags & 1 /* Any */) {
                    return objectType;
                }
                // Defer the operation by creating an indexed access type.
                var id = objectType.id + "," + indexType.id;
                var type = indexedAccessTypes.get(id);
                if (!type) {
                    indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType));
                }
                return type;
            }
            // In the following we resolve T[K] to the type of the property in T selected by K.
            // We treat boolean as different from other unions to improve errors;
            // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'.
            var apparentObjectType = getApparentType(objectType);
            if (indexType.flags & 65536 /* Union */ && !(indexType.flags & 8 /* Boolean */)) {
                var propTypes = [];
                for (var _i = 0, _a = indexType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false);
                    if (propType === unknownType) {
                        return unknownType;
                    }
                    propTypes.push(propType);
                }
                return getUnionType(propTypes);
            }
            return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true);
        }
        function getTypeFromIndexedAccessTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node);
            }
            return links.resolvedType;
        }
        function getTypeFromMappedTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var type = createObjectType(32 /* Mapped */, node.symbol);
                type.declaration = node;
                type.aliasSymbol = getAliasSymbolForTypeNode(node);
                type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
                links.resolvedType = type;
                // Eagerly resolve the constraint type which forces an error if the constraint type circularly
                // references itself through one or more type aliases.
                getConstraintTypeFromMappedType(type);
            }
            return links.resolvedType;
        }
        function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // Deferred resolution of members is handled by resolveObjectTypeMembers
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                if (node.symbol.members.size === 0 && !aliasSymbol) {
                    links.resolvedType = emptyTypeLiteralType;
                }
                else {
                    var type = createObjectType(16 /* Anonymous */, node.symbol);
                    type.aliasSymbol = aliasSymbol;
                    type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
                    if (ts.isJSDocTypeLiteral(node) && node.isArrayType) {
                        type = createArrayType(type);
                    }
                    links.resolvedType = type;
                }
            }
            return links.resolvedType;
        }
        function getAliasSymbolForTypeNode(node) {
            return node.parent.kind === 231 /* TypeAliasDeclaration */ ? getSymbolOfNode(node.parent) : undefined;
        }
        function getAliasTypeArgumentsForTypeNode(node) {
            var symbol = getAliasSymbolForTypeNode(node);
            return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
        }
        /**
         * Since the source of spread types are object literals, which are not binary,
         * this function should be called in a left folding style, with left = previous result of getSpreadType
         * and right = the new element to be spread.
         */
        function getSpreadType(left, right, symbol, propagatedFlags) {
            if (left.flags & 1 /* Any */ || right.flags & 1 /* Any */) {
                return anyType;
            }
            if (left.flags & 8192 /* Never */) {
                return right;
            }
            if (right.flags & 8192 /* Never */) {
                return left;
            }
            if (left.flags & 65536 /* Union */) {
                return mapType(left, function (t) { return getSpreadType(t, right, symbol, propagatedFlags); });
            }
            if (right.flags & 65536 /* Union */) {
                return mapType(right, function (t) { return getSpreadType(left, t, symbol, propagatedFlags); });
            }
            if (right.flags & 16777216 /* NonPrimitive */) {
                return nonPrimitiveType;
            }
            if (right.flags & (136 /* BooleanLike */ | 84 /* NumberLike */ | 262178 /* StringLike */ | 272 /* EnumLike */)) {
                return left;
            }
            var members = ts.createSymbolTable();
            var skippedPrivateMembers = ts.createUnderscoreEscapedMap();
            var stringIndexInfo;
            var numberIndexInfo;
            if (left === emptyObjectType) {
                // for the first spread element, left === emptyObjectType, so take the right's string indexer
                stringIndexInfo = getIndexInfoOfType(right, 0 /* String */);
                numberIndexInfo = getIndexInfoOfType(right, 1 /* Number */);
            }
            else {
                stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 0 /* String */), getIndexInfoOfType(right, 0 /* String */));
                numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 1 /* Number */), getIndexInfoOfType(right, 1 /* Number */));
            }
            for (var _i = 0, _a = getPropertiesOfType(right); _i < _a.length; _i++) {
                var rightProp = _a[_i];
                // we approximate own properties as non-methods plus methods that are inside the object literal
                var isSetterWithoutGetter = rightProp.flags & 65536 /* SetAccessor */ && !(rightProp.flags & 32768 /* GetAccessor */);
                if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (8 /* Private */ | 16 /* Protected */)) {
                    skippedPrivateMembers.set(rightProp.escapedName, true);
                }
                else if (!isClassMethod(rightProp) && !isSetterWithoutGetter) {
                    members.set(rightProp.escapedName, getNonReadonlySymbol(rightProp));
                }
            }
            for (var _b = 0, _c = getPropertiesOfType(left); _b < _c.length; _b++) {
                var leftProp = _c[_b];
                if (leftProp.flags & 65536 /* SetAccessor */ && !(leftProp.flags & 32768 /* GetAccessor */)
                    || skippedPrivateMembers.has(leftProp.escapedName)
                    || isClassMethod(leftProp)) {
                    continue;
                }
                if (members.has(leftProp.escapedName)) {
                    var rightProp = members.get(leftProp.escapedName);
                    var rightType = getTypeOfSymbol(rightProp);
                    if (rightProp.flags & 16777216 /* Optional */) {
                        var declarations = ts.concatenate(leftProp.declarations, rightProp.declarations);
                        var flags = 4 /* Property */ | (leftProp.flags & 16777216 /* Optional */);
                        var result = createSymbol(flags, leftProp.escapedName);
                        result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, 131072 /* NEUndefined */)]);
                        result.leftSpread = leftProp;
                        result.rightSpread = rightProp;
                        result.declarations = declarations;
                        members.set(leftProp.escapedName, result);
                    }
                }
                else {
                    members.set(leftProp.escapedName, getNonReadonlySymbol(leftProp));
                }
            }
            var spread = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
            spread.flags |= propagatedFlags;
            spread.flags |= 1048576 /* FreshLiteral */ | 4194304 /* ContainsObjectLiteral */;
            spread.objectFlags |= 128 /* ObjectLiteral */;
            spread.symbol = symbol;
            return spread;
        }
        function getNonReadonlySymbol(prop) {
            if (!isReadonlySymbol(prop)) {
                return prop;
            }
            var flags = 4 /* Property */ | (prop.flags & 16777216 /* Optional */);
            var result = createSymbol(flags, prop.escapedName);
            result.type = getTypeOfSymbol(prop);
            result.declarations = prop.declarations;
            result.syntheticOrigin = prop;
            return result;
        }
        function isClassMethod(prop) {
            return prop.flags & 8192 /* Method */ && ts.find(prop.declarations, function (decl) { return ts.isClassLike(decl.parent); });
        }
        function createLiteralType(flags, value, symbol) {
            var type = createType(flags);
            type.symbol = symbol;
            type.value = value;
            return type;
        }
        function getFreshTypeOfLiteralType(type) {
            if (type.flags & 96 /* StringOrNumberLiteral */ && !(type.flags & 1048576 /* FreshLiteral */)) {
                if (!type.freshType) {
                    var freshType = createLiteralType(type.flags | 1048576 /* FreshLiteral */, type.value, type.symbol);
                    freshType.regularType = type;
                    type.freshType = freshType;
                }
                return type.freshType;
            }
            return type;
        }
        function getRegularTypeOfLiteralType(type) {
            return type.flags & 96 /* StringOrNumberLiteral */ && type.flags & 1048576 /* FreshLiteral */ ? type.regularType : type;
        }
        function getLiteralType(value, enumId, symbol) {
            // We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
            // where NNN is the text representation of a numeric literal and SSS are the characters
            // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
            // EEE is a unique id for the containing enum type.
            var qualifier = typeof value === "number" ? "#" : "@";
            var key = enumId ? enumId + qualifier + value : qualifier + value;
            var type = literalTypes.get(key);
            if (!type) {
                var flags = (typeof value === "number" ? 64 /* NumberLiteral */ : 32 /* StringLiteral */) | (enumId ? 256 /* EnumLiteral */ : 0);
                literalTypes.set(key, type = createLiteralType(flags, value, symbol));
            }
            return type;
        }
        function getTypeFromLiteralTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
            }
            return links.resolvedType;
        }
        function getTypeFromJSDocVariadicType(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var type = getTypeFromTypeNode(node.type);
                links.resolvedType = type ? createArrayType(type) : unknownType;
            }
            return links.resolvedType;
        }
        function getThisType(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            var parent = container && container.parent;
            if (parent && (ts.isClassLike(parent) || parent.kind === 230 /* InterfaceDeclaration */)) {
                if (!ts.hasModifier(container, 32 /* Static */) &&
                    (container.kind !== 152 /* Constructor */ || ts.isNodeDescendantOf(node, container.body))) {
                    return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
                }
            }
            error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface);
            return unknownType;
        }
        function getTypeFromThisTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getThisType(node);
            }
            return links.resolvedType;
        }
        function getTypeFromTypeNode(node) {
            switch (node.kind) {
                case 119 /* AnyKeyword */:
                case 268 /* JSDocAllType */:
                case 269 /* JSDocUnknownType */:
                    return anyType;
                case 136 /* StringKeyword */:
                    return stringType;
                case 133 /* NumberKeyword */:
                    return numberType;
                case 122 /* BooleanKeyword */:
                    return booleanType;
                case 137 /* SymbolKeyword */:
                    return esSymbolType;
                case 105 /* VoidKeyword */:
                    return voidType;
                case 139 /* UndefinedKeyword */:
                    return undefinedType;
                case 95 /* NullKeyword */:
                    return nullType;
                case 130 /* NeverKeyword */:
                    return neverType;
                case 134 /* ObjectKeyword */:
                    return node.flags & 65536 /* JavaScriptFile */ ? anyType : nonPrimitiveType;
                case 169 /* ThisType */:
                case 99 /* ThisKeyword */:
                    return getTypeFromThisTypeNode(node);
                case 173 /* LiteralType */:
                    return getTypeFromLiteralTypeNode(node);
                case 159 /* TypeReference */:
                    return getTypeFromTypeReference(node);
                case 158 /* TypePredicate */:
                    return booleanType;
                case 201 /* ExpressionWithTypeArguments */:
                    return getTypeFromTypeReference(node);
                case 162 /* TypeQuery */:
                    return getTypeFromTypeQueryNode(node);
                case 164 /* ArrayType */:
                    return getTypeFromArrayTypeNode(node);
                case 165 /* TupleType */:
                    return getTypeFromTupleTypeNode(node);
                case 166 /* UnionType */:
                    return getTypeFromUnionTypeNode(node);
                case 167 /* IntersectionType */:
                    return getTypeFromIntersectionTypeNode(node);
                case 270 /* JSDocNullableType */:
                    return getTypeFromJSDocNullableTypeNode(node);
                case 168 /* ParenthesizedType */:
                case 271 /* JSDocNonNullableType */:
                case 272 /* JSDocOptionalType */:
                case 267 /* JSDocTypeExpression */:
                    return getTypeFromTypeNode(node.type);
                case 160 /* FunctionType */:
                case 161 /* ConstructorType */:
                case 163 /* TypeLiteral */:
                case 285 /* JSDocTypeLiteral */:
                case 273 /* JSDocFunctionType */:
                    return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                case 170 /* TypeOperator */:
                    return getTypeFromTypeOperatorNode(node);
                case 171 /* IndexedAccessType */:
                    return getTypeFromIndexedAccessTypeNode(node);
                case 172 /* MappedType */:
                    return getTypeFromMappedTypeNode(node);
                // This function assumes that an identifier or qualified name is a type expression
                // Callers should first ensure this by calling isTypeNode
                case 71 /* Identifier */:
                case 143 /* QualifiedName */:
                    var symbol = getSymbolAtLocation(node);
                    return symbol && getDeclaredTypeOfSymbol(symbol);
                case 274 /* JSDocVariadicType */:
                    return getTypeFromJSDocVariadicType(node);
                default:
                    return unknownType;
            }
        }
        function instantiateList(items, mapper, instantiator) {
            if (items && items.length) {
                var result = [];
                for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
                    var v = items_1[_i];
                    result.push(instantiator(v, mapper));
                }
                return result;
            }
            return items;
        }
        function instantiateTypes(types, mapper) {
            return instantiateList(types, mapper, instantiateType);
        }
        function instantiateSignatures(signatures, mapper) {
            return instantiateList(signatures, mapper, instantiateSignature);
        }
        function makeUnaryTypeMapper(source, target) {
            return function (t) { return t === source ? target : t; };
        }
        function makeBinaryTypeMapper(source1, target1, source2, target2) {
            return function (t) { return t === source1 ? target1 : t === source2 ? target2 : t; };
        }
        function makeArrayTypeMapper(sources, targets) {
            return function (t) {
                for (var i = 0; i < sources.length; i++) {
                    if (t === sources[i]) {
                        return targets ? targets[i] : anyType;
                    }
                }
                return t;
            };
        }
        function createTypeMapper(sources, targets) {
            ts.Debug.assert(targets === undefined || sources.length === targets.length);
            return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
                sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
                    makeArrayTypeMapper(sources, targets);
        }
        function createTypeEraser(sources) {
            return createTypeMapper(sources, /*targets*/ undefined);
        }
        /**
         * Maps forward-references to later types parameters to the empty object type.
         * This is used during inference when instantiating type parameter defaults.
         */
        function createBackreferenceMapper(typeParameters, index) {
            return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; };
        }
        function isInferenceContext(mapper) {
            return !!mapper.signature;
        }
        function cloneTypeMapper(mapper) {
            return mapper && isInferenceContext(mapper) ?
                createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.compareTypes, mapper.inferences) :
                mapper;
        }
        function combineTypeMappers(mapper1, mapper2) {
            return function (t) { return instantiateType(mapper1(t), mapper2); };
        }
        function createReplacementMapper(source, target, baseMapper) {
            return function (t) { return t === source ? target : baseMapper(t); };
        }
        function cloneTypeParameter(typeParameter) {
            var result = createType(16384 /* TypeParameter */);
            result.symbol = typeParameter.symbol;
            result.target = typeParameter;
            return result;
        }
        function cloneTypePredicate(predicate, mapper) {
            if (ts.isIdentifierTypePredicate(predicate)) {
                return {
                    kind: 1 /* Identifier */,
                    parameterName: predicate.parameterName,
                    parameterIndex: predicate.parameterIndex,
                    type: instantiateType(predicate.type, mapper)
                };
            }
            else {
                return {
                    kind: 0 /* This */,
                    type: instantiateType(predicate.type, mapper)
                };
            }
        }
        function instantiateSignature(signature, mapper, eraseTypeParameters) {
            var freshTypeParameters;
            var freshTypePredicate;
            if (signature.typeParameters && !eraseTypeParameters) {
                // First create a fresh set of type parameters, then include a mapping from the old to the
                // new type parameters in the mapper function. Finally store this mapper in the new type
                // parameters such that we can use it when instantiating constraints.
                freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter);
                mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
                for (var _i = 0, freshTypeParameters_1 = freshTypeParameters; _i < freshTypeParameters_1.length; _i++) {
                    var tp = freshTypeParameters_1[_i];
                    tp.mapper = mapper;
                }
            }
            if (signature.typePredicate) {
                freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
            }
            var result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), 
            /*resolvedReturnType*/ undefined, freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
            result.target = signature;
            result.mapper = mapper;
            return result;
        }
        function instantiateSymbol(symbol, mapper) {
            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                var links = getSymbolLinks(symbol);
                // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
                // type mappers. This ensures that original type identities are properly preserved and that aliases
                // always reference a non-aliases.
                symbol = links.target;
                mapper = combineTypeMappers(links.mapper, mapper);
            }
            // Keep the flags from the symbol we're instantiating.  Mark that is instantiated, and
            // also transient so that we can just store data on it directly.
            var result = createSymbol(symbol.flags, symbol.escapedName);
            result.checkFlags = 1 /* Instantiated */;
            result.declarations = symbol.declarations;
            result.parent = symbol.parent;
            result.target = symbol;
            result.mapper = mapper;
            if (symbol.valueDeclaration) {
                result.valueDeclaration = symbol.valueDeclaration;
            }
            if (symbol.isRestParameter) {
                result.isRestParameter = symbol.isRestParameter;
            }
            return result;
        }
        function getAnonymousTypeInstantiation(type, mapper) {
            var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type;
            var symbol = target.symbol;
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            if (!typeParameters) {
                // The first time an anonymous type is instantiated we compute and store a list of the type
                // parameters that are in scope (and therefore potentially referenced). For type literals that
                // aren't the right hand side of a generic type alias declaration we optimize by reducing the
                // set of type parameters to those that are possibly referenced in the literal.
                var declaration_1 = symbol.declarations[0];
                var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true) || ts.emptyArray;
                typeParameters = symbol.flags & 2048 /* TypeLiteral */ && !target.aliasTypeArguments ?
                    ts.filter(outerTypeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, declaration_1); }) :
                    outerTypeParameters;
                links.typeParameters = typeParameters;
                if (typeParameters.length) {
                    links.instantiations = ts.createMap();
                    links.instantiations.set(getTypeListId(typeParameters), target);
                }
            }
            if (typeParameters.length) {
                // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var combinedMapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper;
                var typeArguments = ts.map(typeParameters, combinedMapper);
                var id = getTypeListId(typeArguments);
                var result = links.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(typeParameters, typeArguments);
                    result = target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper);
                    links.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function isTypeParameterPossiblyReferenced(tp, node) {
            // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks
            // between the node and the type parameter declaration, if the node contains actual references to the
            // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced.
            if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) {
                var container_1 = tp.symbol.declarations[0].parent;
                if (ts.findAncestor(node, function (n) { return n.kind === 207 /* Block */ ? "quit" : n === container_1; })) {
                    return ts.forEachChild(node, containsReference);
                }
            }
            return true;
            function containsReference(node) {
                switch (node.kind) {
                    case 169 /* ThisType */:
                        return tp.isThisType;
                    case 71 /* Identifier */:
                        return !tp.isThisType && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp;
                    case 162 /* TypeQuery */:
                        return true;
                }
                return ts.forEachChild(node, containsReference);
            }
        }
        function instantiateMappedType(type, mapper) {
            // Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some
            // type variable T. If so, the mapped type is distributive over a union type and when T is instantiated
            // to a union type A | B, we produce { [P in keyof A]: X } | { [P in keyof B]: X }. Furthermore, for
            // homomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a
            // union type A | undefined, we produce { [P in keyof A]: X } | undefined.
            var constraintType = getConstraintTypeFromMappedType(type);
            if (constraintType.flags & 262144 /* Index */) {
                var typeVariable_1 = constraintType.type;
                if (typeVariable_1.flags & 16384 /* TypeParameter */) {
                    var mappedTypeVariable = instantiateType(typeVariable_1, mapper);
                    if (typeVariable_1 !== mappedTypeVariable) {
                        return mapType(mappedTypeVariable, function (t) {
                            if (isMappableType(t)) {
                                return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper));
                            }
                            return t;
                        });
                    }
                }
            }
            return instantiateAnonymousType(type, mapper);
        }
        function isMappableType(type) {
            return type.flags & (1 /* Any */ | 16384 /* TypeParameter */ | 32768 /* Object */ | 131072 /* Intersection */ | 524288 /* IndexedAccess */);
        }
        function instantiateAnonymousType(type, mapper) {
            var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol);
            if (type.objectFlags & 32 /* Mapped */) {
                result.declaration = type.declaration;
            }
            result.target = type;
            result.mapper = mapper;
            result.aliasSymbol = type.aliasSymbol;
            result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
            return result;
        }
        function instantiateType(type, mapper) {
            if (type && mapper !== identityMapper) {
                if (type.flags & 16384 /* TypeParameter */) {
                    return mapper(type);
                }
                if (type.flags & 32768 /* Object */) {
                    if (type.objectFlags & 16 /* Anonymous */) {
                        // If the anonymous type originates in a declaration of a function, method, class, or
                        // interface, in an object type literal, or in an object literal expression, we may need
                        // to instantiate the type because it might reference a type parameter.
                        return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ?
                            getAnonymousTypeInstantiation(type, mapper) : type;
                    }
                    if (type.objectFlags & 32 /* Mapped */) {
                        return getAnonymousTypeInstantiation(type, mapper);
                    }
                    if (type.objectFlags & 4 /* Reference */) {
                        return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper));
                    }
                }
                if (type.flags & 65536 /* Union */ && !(type.flags & 8190 /* Primitive */)) {
                    return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
                }
                if (type.flags & 131072 /* Intersection */) {
                    return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
                }
                if (type.flags & 262144 /* Index */) {
                    return getIndexType(instantiateType(type.type, mapper));
                }
                if (type.flags & 524288 /* IndexedAccess */) {
                    return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper));
                }
            }
            return type;
        }
        function instantiateIndexInfo(info, mapper) {
            return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration);
        }
        // Returns true if the given expression contains (at any level of nesting) a function or arrow expression
        // that is subject to contextual typing.
        function isContextSensitive(node) {
            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            switch (node.kind) {
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                case 151 /* MethodDeclaration */:
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 178 /* ObjectLiteralExpression */:
                    return ts.forEach(node.properties, isContextSensitive);
                case 177 /* ArrayLiteralExpression */:
                    return ts.forEach(node.elements, isContextSensitive);
                case 195 /* ConditionalExpression */:
                    return isContextSensitive(node.whenTrue) ||
                        isContextSensitive(node.whenFalse);
                case 194 /* BinaryExpression */:
                    return node.operatorToken.kind === 54 /* BarBarToken */ &&
                        (isContextSensitive(node.left) || isContextSensitive(node.right));
                case 261 /* PropertyAssignment */:
                    return isContextSensitive(node.initializer);
                case 185 /* ParenthesizedExpression */:
                    return isContextSensitive(node.expression);
                case 254 /* JsxAttributes */:
                    return ts.forEach(node.properties, isContextSensitive);
                case 253 /* JsxAttribute */:
                    // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive.
                    return node.initializer && isContextSensitive(node.initializer);
                case 256 /* JsxExpression */:
                    // It is possible to that node.expression is undefined (e.g <div x={} />)
                    return node.expression && isContextSensitive(node.expression);
            }
            return false;
        }
        function isContextSensitiveFunctionLikeDeclaration(node) {
            // Functions with type parameters are not context sensitive.
            if (node.typeParameters) {
                return false;
            }
            // Functions with any parameters that lack type annotations are context sensitive.
            if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) {
                return true;
            }
            if (node.kind !== 187 /* ArrowFunction */) {
                // If the first parameter is not an explicit 'this' parameter, then the function has
                // an implicit 'this' parameter which is subject to contextual typing.
                var parameter = ts.firstOrUndefined(node.parameters);
                if (!(parameter && ts.parameterIsThisKeyword(parameter))) {
                    return true;
                }
            }
            // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
            return node.body.kind === 207 /* Block */ ? false : isContextSensitive(node.body);
        }
        function isContextSensitiveFunctionOrObjectLiteralMethod(func) {
            return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
        }
        function getTypeWithoutSignatures(type) {
            if (type.flags & 32768 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.constructSignatures.length) {
                    var result = createObjectType(16 /* Anonymous */, type.symbol);
                    result.members = resolved.members;
                    result.properties = resolved.properties;
                    result.callSignatures = ts.emptyArray;
                    result.constructSignatures = ts.emptyArray;
                    return result;
                }
            }
            else if (type.flags & 131072 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, getTypeWithoutSignatures));
            }
            return type;
        }
        // TYPE CHECKING
        function isTypeIdenticalTo(source, target) {
            return isTypeRelatedTo(source, target, identityRelation);
        }
        function compareTypesIdentical(source, target) {
            return isTypeRelatedTo(source, target, identityRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesAssignable(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation) ? -1 /* True */ : 0 /* False */;
        }
        function isTypeSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation);
        }
        function isTypeAssignableTo(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation);
        }
        // A type S is considered to be an instance of a type T if S and T are the same type or if S is a
        // subtype of T but not structurally identical to T. This specifically means that two distinct but
        // structurally identical types (such as two classes) are not considered instances of each other.
        function isTypeInstanceOf(source, target) {
            return getTargetType(source) === getTargetType(target) || isTypeSubtypeOf(source, target) && !isTypeIdenticalTo(source, target);
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
         *
         * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
         * It is used to check following cases:
         *   - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
         *   - the types of `case` clause expressions and their respective `switch` expressions.
         *   - the type of an expression in a type assertion with the type being asserted.
         */
        function isTypeComparableTo(source, target) {
            return isTypeRelatedTo(source, target, comparableRelation);
        }
        function areTypesComparable(type1, type2) {
            return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
        }
        function checkTypeAssignableTo(source, target, errorNode, headMessage, containingMessageChain) {
            return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain);
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'.
         */
        function checkTypeComparableTo(source, target, errorNode, headMessage, containingMessageChain) {
            return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain);
        }
        function isSignatureAssignableTo(source, target, ignoreReturnTypes) {
            return compareSignaturesRelated(source, target, 0 /* None */, ignoreReturnTypes, /*reportErrors*/ false, 
            /*errorReporter*/ undefined, compareTypesAssignable) !== 0 /* False */;
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesRelated(source, target, callbackCheck, ignoreReturnTypes, reportErrors, errorReporter, compareTypes) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) {
                return 0 /* False */;
            }
            if (source.typeParameters && source.typeParameters !== target.typeParameters) {
                target = getCanonicalSignature(target);
                source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes);
            }
            var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
            var strictVariance = !callbackCheck && strictFunctionTypes && kind !== 151 /* MethodDeclaration */ &&
                kind !== 150 /* MethodSignature */ && kind !== 152 /* Constructor */;
            var result = -1 /* True */;
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType && sourceThisType !== voidType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    // void sources are assignable to anything.
                    var related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false)
                        || compareTypes(targetThisType, sourceThisType, reportErrors);
                    if (!related) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible);
                        }
                        return 0 /* False */;
                    }
                    result &= related;
                }
            }
            var sourceMax = getNumNonRestParameters(source);
            var targetMax = getNumNonRestParameters(target);
            var checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, target, targetMax);
            var sourceParams = source.parameters;
            var targetParams = target.parameters;
            for (var i = 0; i < checkCount; i++) {
                var sourceType = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source);
                var targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target);
                // In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
                // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
                // they naturally relate only contra-variantly). However, if the source and target parameters both have
                // function types with a single call signature, we know we are relating two callback parameters. In
                // that case it is sufficient to only relate the parameters of the signatures co-variantly because,
                // similar to return values, callback parameters are output positions. This means that a Promise<T>,
                // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
                // with respect to T.
                var sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
                var targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType));
                var callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate &&
                    (getFalsyFlags(sourceType) & 6144 /* Nullable */) === (getFalsyFlags(targetType) & 6144 /* Nullable */);
                var related = callbacks ?
                    compareSignaturesRelated(targetSig, sourceSig, strictVariance ? 2 /* Strict */ : 1 /* Bivariant */, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
                    !callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
                if (!related) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.symbolName(sourceParams[i < sourceMax ? i : sourceMax]), ts.symbolName(targetParams[i < targetMax ? i : targetMax]));
                    }
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!ignoreReturnTypes) {
                var targetReturnType = getReturnTypeOfSignature(target);
                if (targetReturnType === voidType) {
                    return result;
                }
                var sourceReturnType = getReturnTypeOfSignature(source);
                // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
                if (target.typePredicate) {
                    if (source.typePredicate) {
                        result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
                    }
                    else if (ts.isIdentifierTypePredicate(target.typePredicate)) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
                        }
                        return 0 /* False */;
                    }
                }
                else {
                    // When relating callback signatures, we still need to relate return types bi-variantly as otherwise
                    // the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
                    // wouldn't be co-variant for T without this rule.
                    result &= callbackCheck === 1 /* Bivariant */ && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
                        compareTypes(sourceReturnType, targetReturnType, reportErrors);
                }
            }
            return result;
        }
        function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) {
            if (source.kind !== target.kind) {
                if (reportErrors) {
                    errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard);
                    errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                }
                return 0 /* False */;
            }
            if (source.kind === 1 /* Identifier */) {
                var sourcePredicate = source;
                var targetPredicate = target;
                var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0);
                var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0);
                if (sourceIndex !== targetIndex) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName);
                        errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                    }
                    return 0 /* False */;
                }
            }
            var related = compareTypes(source.type, target.type, reportErrors);
            if (related === 0 /* False */ && reportErrors) {
                errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
            }
            return related;
        }
        function isImplementationCompatibleWithOverload(implementation, overload) {
            var erasedSource = getErasedSignature(implementation);
            var erasedTarget = getErasedSignature(overload);
            // First see if the return types are compatible in either direction.
            var sourceReturnType = getReturnTypeOfSignature(erasedSource);
            var targetReturnType = getReturnTypeOfSignature(erasedTarget);
            if (targetReturnType === voidType
                || isTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation)
                || isTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation)) {
                return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
            }
            return false;
        }
        function getNumNonRestParameters(signature) {
            var numParams = signature.parameters.length;
            return signature.hasRestParameter ?
                numParams - 1 :
                numParams;
        }
        function getNumParametersToCheckForSignatureRelatability(source, sourceNonRestParamCount, target, targetNonRestParamCount) {
            if (source.hasRestParameter === target.hasRestParameter) {
                if (source.hasRestParameter) {
                    // If both have rest parameters, get the max and add 1 to
                    // compensate for the rest parameter.
                    return Math.max(sourceNonRestParamCount, targetNonRestParamCount) + 1;
                }
                else {
                    return Math.min(sourceNonRestParamCount, targetNonRestParamCount);
                }
            }
            else {
                // Return the count for whichever signature doesn't have rest parameters.
                return source.hasRestParameter ?
                    targetNonRestParamCount :
                    sourceNonRestParamCount;
            }
        }
        function isEmptyResolvedType(t) {
            return t.properties.length === 0 &&
                t.callSignatures.length === 0 &&
                t.constructSignatures.length === 0 &&
                !t.stringIndexInfo &&
                !t.numberIndexInfo;
        }
        function isEmptyObjectType(type) {
            return type.flags & 32768 /* Object */ ? isEmptyResolvedType(resolveStructuredTypeMembers(type)) :
                type.flags & 16777216 /* NonPrimitive */ ? true :
                    type.flags & 65536 /* Union */ ? ts.forEach(type.types, isEmptyObjectType) :
                        type.flags & 131072 /* Intersection */ ? !ts.forEach(type.types, function (t) { return !isEmptyObjectType(t); }) :
                            false;
        }
        function isEnumTypeRelatedTo(sourceSymbol, targetSymbol, errorReporter) {
            if (sourceSymbol === targetSymbol) {
                return true;
            }
            var id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
            var relation = enumRelation.get(id);
            if (relation !== undefined) {
                return relation;
            }
            if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & 256 /* RegularEnum */) || !(targetSymbol.flags & 256 /* RegularEnum */)) {
                enumRelation.set(id, false);
                return false;
            }
            var targetEnumType = getTypeOfSymbol(targetSymbol);
            for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(sourceSymbol)); _i < _a.length; _i++) {
                var property = _a[_i];
                if (property.flags & 8 /* EnumMember */) {
                    var targetProperty = getPropertyOfType(targetEnumType, property.escapedName);
                    if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) {
                        if (errorReporter) {
                            errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */));
                        }
                        enumRelation.set(id, false);
                        return false;
                    }
                }
            }
            enumRelation.set(id, true);
            return true;
        }
        function isSimpleTypeRelatedTo(source, target, relation, errorReporter) {
            var s = source.flags;
            var t = target.flags;
            if (t & 8192 /* Never */)
                return false;
            if (t & 1 /* Any */ || s & 8192 /* Never */)
                return true;
            if (s & 262178 /* StringLike */ && t & 2 /* String */)
                return true;
            if (s & 32 /* StringLiteral */ && s & 256 /* EnumLiteral */ &&
                t & 32 /* StringLiteral */ && !(t & 256 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 84 /* NumberLike */ && t & 4 /* Number */)
                return true;
            if (s & 64 /* NumberLiteral */ && s & 256 /* EnumLiteral */ &&
                t & 64 /* NumberLiteral */ && !(t & 256 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 136 /* BooleanLike */ && t & 8 /* Boolean */)
                return true;
            if (s & 16 /* Enum */ && t & 16 /* Enum */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                return true;
            if (s & 256 /* EnumLiteral */ && t & 256 /* EnumLiteral */) {
                if (s & 65536 /* Union */ && t & 65536 /* Union */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                    return true;
                if (s & 224 /* Literal */ && t & 224 /* Literal */ &&
                    source.value === target.value &&
                    isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter))
                    return true;
            }
            if (s & 2048 /* Undefined */ && (!strictNullChecks || t & (2048 /* Undefined */ | 1024 /* Void */)))
                return true;
            if (s & 4096 /* Null */ && (!strictNullChecks || t & 4096 /* Null */))
                return true;
            if (s & 32768 /* Object */ && t & 16777216 /* NonPrimitive */)
                return true;
            if (relation === assignableRelation || relation === comparableRelation) {
                if (s & 1 /* Any */)
                    return true;
                // Type number or any numeric literal type is assignable to any numeric enum type or any
                // numeric enum literal type. This rule exists for backwards compatibility reasons because
                // bit-flag enum types sometimes look like literal enum types with numeric literal values.
                if (s & (4 /* Number */ | 64 /* NumberLiteral */) && !(s & 256 /* EnumLiteral */) && (t & 16 /* Enum */ || t & 64 /* NumberLiteral */ && t & 256 /* EnumLiteral */))
                    return true;
            }
            return false;
        }
        function isTypeRelatedTo(source, target, relation) {
            if (source.flags & 96 /* StringOrNumberLiteral */ && source.flags & 1048576 /* FreshLiteral */) {
                source = source.regularType;
            }
            if (target.flags & 96 /* StringOrNumberLiteral */ && target.flags & 1048576 /* FreshLiteral */) {
                target = target.regularType;
            }
            if (source === target || relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) {
                return true;
            }
            if (source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */) {
                var related = relation.get(getRelationKey(source, target, relation));
                if (related !== undefined) {
                    return related === 1 /* Succeeded */;
                }
            }
            if (source.flags & 1032192 /* StructuredOrTypeVariable */ || target.flags & 1032192 /* StructuredOrTypeVariable */) {
                return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined);
            }
            return false;
        }
        /**
         * Checks if 'source' is related to 'target' (e.g.: is a assignable to).
         * @param source The left-hand-side of the relation.
         * @param target The right-hand-side of the relation.
         * @param relation The relation considered. One of 'identityRelation', 'subtypeRelation', 'assignableRelation', or 'comparableRelation'.
         * Used as both to determine which checks are performed and as a cache of previously computed results.
         * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used.
         * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used.
         * @param containingMessageChain A chain of errors to prepend any new errors found.
         */
        function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain) {
            var errorInfo;
            var maybeKeys;
            var sourceStack;
            var targetStack;
            var maybeCount = 0;
            var depth = 0;
            var ExpandingFlags;
            (function (ExpandingFlags) {
                ExpandingFlags[ExpandingFlags["None"] = 0] = "None";
                ExpandingFlags[ExpandingFlags["Source"] = 1] = "Source";
                ExpandingFlags[ExpandingFlags["Target"] = 2] = "Target";
                ExpandingFlags[ExpandingFlags["Both"] = 3] = "Both";
            })(ExpandingFlags || (ExpandingFlags = {}));
            var expandingFlags = 0 /* None */;
            var overflow = false;
            var isIntersectionConstituent = false;
            ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
            var result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage);
            if (overflow) {
                error(errorNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
            }
            else if (errorInfo) {
                if (containingMessageChain) {
                    errorInfo = ts.concatenateDiagnosticMessageChains(containingMessageChain, errorInfo);
                }
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo));
            }
            return result !== 0 /* False */;
            function reportError(message, arg0, arg1, arg2) {
                ts.Debug.assert(!!errorNode);
                errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2);
            }
            function reportRelationError(message, source, target) {
                var sourceType = typeToString(source);
                var targetType = typeToString(target);
                if (sourceType === targetType) {
                    sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */);
                    targetType = typeToString(target, /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */);
                }
                if (!message) {
                    if (relation === comparableRelation) {
                        message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1;
                    }
                    else if (sourceType === targetType) {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
                    }
                    else {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
                    }
                }
                reportError(message, sourceType, targetType);
            }
            function tryElaborateErrorsForPrimitivesAndObjects(source, target) {
                var sourceType = typeToString(source);
                var targetType = typeToString(target);
                if ((globalStringType === source && stringType === target) ||
                    (globalNumberType === source && numberType === target) ||
                    (globalBooleanType === source && booleanType === target) ||
                    (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) {
                    reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType);
                }
            }
            function isUnionOrIntersectionTypeWithoutNullableConstituents(type) {
                if (!(type.flags & 196608 /* UnionOrIntersection */)) {
                    return false;
                }
                // at this point we know that this is union or intersection type possibly with nullable constituents.
                // check if we still will have compound type if we ignore nullable components.
                var seenNonNullable = false;
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (t.flags & 6144 /* Nullable */) {
                        continue;
                    }
                    if (seenNonNullable) {
                        return true;
                    }
                    seenNonNullable = true;
                }
                return false;
            }
            /**
             * Compare two types and return
             * * Ternary.True if they are related with no assumptions,
             * * Ternary.Maybe if they are related with assumptions of other relationships, or
             * * Ternary.False if they are not related.
             */
            function isRelatedTo(source, target, reportErrors, headMessage) {
                if (source.flags & 96 /* StringOrNumberLiteral */ && source.flags & 1048576 /* FreshLiteral */) {
                    source = source.regularType;
                }
                if (target.flags & 96 /* StringOrNumberLiteral */ && target.flags & 1048576 /* FreshLiteral */) {
                    target = target.regularType;
                }
                // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
                if (source === target)
                    return -1 /* True */;
                if (relation === identityRelation) {
                    return isIdenticalTo(source, target);
                }
                if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined))
                    return -1 /* True */;
                if (getObjectFlags(source) & 128 /* ObjectLiteral */ && source.flags & 1048576 /* FreshLiteral */) {
                    if (hasExcessProperties(source, target, reportErrors)) {
                        if (reportErrors) {
                            reportRelationError(headMessage, source, target);
                        }
                        return 0 /* False */;
                    }
                    // Above we check for excess properties with respect to the entire target type. When union
                    // and intersection types are further deconstructed on the target side, we don't want to
                    // make the check again (as it might fail for a partial target type). Therefore we obtain
                    // the regular source type and proceed with that.
                    if (isUnionOrIntersectionTypeWithoutNullableConstituents(target)) {
                        source = getRegularTypeOfObjectLiteral(source);
                    }
                }
                if (relation !== comparableRelation &&
                    !(source.flags & 196608 /* UnionOrIntersection */) &&
                    !(target.flags & 65536 /* Union */) &&
                    !isIntersectionConstituent &&
                    source !== globalObjectType &&
                    (getPropertiesOfType(source).length > 0 ||
                        getSignaturesOfType(source, 0 /* Call */).length > 0 ||
                        getSignaturesOfType(source, 1 /* Construct */).length > 0) &&
                    isWeakType(target) &&
                    !hasCommonProperties(source, target)) {
                    if (reportErrors) {
                        var calls = getSignaturesOfType(source, 0 /* Call */);
                        var constructs = getSignaturesOfType(source, 1 /* Construct */);
                        if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) ||
                            constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) {
                            reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target));
                        }
                        else {
                            reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target));
                        }
                    }
                    return 0 /* False */;
                }
                var result = 0 /* False */;
                var saveErrorInfo = errorInfo;
                var saveIsIntersectionConstituent = isIntersectionConstituent;
                isIntersectionConstituent = false;
                // Note that these checks are specifically ordered to produce correct results. In particular,
                // we need to deconstruct unions before intersections (because unions are always at the top),
                // and we need to handle "each" relations before "some" relations for the same kind of type.
                if (source.flags & 65536 /* Union */) {
                    result = relation === comparableRelation ?
                        someTypeRelatedToType(source, target, reportErrors && !(source.flags & 8190 /* Primitive */)) :
                        eachTypeRelatedToType(source, target, reportErrors && !(source.flags & 8190 /* Primitive */));
                }
                else {
                    if (target.flags & 65536 /* Union */) {
                        result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & 8190 /* Primitive */) && !(target.flags & 8190 /* Primitive */));
                    }
                    else if (target.flags & 131072 /* Intersection */) {
                        isIntersectionConstituent = true;
                        result = typeRelatedToEachType(source, target, reportErrors);
                    }
                    else if (source.flags & 131072 /* Intersection */) {
                        // Check to see if any constituents of the intersection are immediately related to the target.
                        //
                        // Don't report errors though. Checking whether a constituent is related to the source is not actually
                        // useful and leads to some confusing error messages. Instead it is better to let the below checks
                        // take care of this, or to not elaborate at all. For instance,
                        //
                        //    - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
                        //
                        //    - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
                        //          than to report that 'D' is not assignable to 'A' or 'B'.
                        //
                        //    - For a primitive type or type parameter (such as 'number = A & B') there is no point in
                        //          breaking the intersection apart.
                        result = someTypeRelatedToType(source, target, /*reportErrors*/ false);
                    }
                    if (!result && (source.flags & 1032192 /* StructuredOrTypeVariable */ || target.flags & 1032192 /* StructuredOrTypeVariable */)) {
                        if (result = recursiveTypeRelatedTo(source, target, reportErrors)) {
                            errorInfo = saveErrorInfo;
                        }
                    }
                }
                isIntersectionConstituent = saveIsIntersectionConstituent;
                if (!result && reportErrors) {
                    if (source.flags & 32768 /* Object */ && target.flags & 8190 /* Primitive */) {
                        tryElaborateErrorsForPrimitivesAndObjects(source, target);
                    }
                    else if (source.symbol && source.flags & 32768 /* Object */ && globalObjectType === source) {
                        reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
                    }
                    reportRelationError(headMessage, source, target);
                }
                return result;
            }
            function isIdenticalTo(source, target) {
                var result;
                if (source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */) {
                    return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false);
                }
                if (source.flags & 65536 /* Union */ && target.flags & 65536 /* Union */ ||
                    source.flags & 131072 /* Intersection */ && target.flags & 131072 /* Intersection */) {
                    if (result = eachTypeRelatedToSomeType(source, target)) {
                        if (result &= eachTypeRelatedToSomeType(target, source)) {
                            return result;
                        }
                    }
                }
                return 0 /* False */;
            }
            function hasExcessProperties(source, target, reportErrors) {
                if (maybeTypeOfKind(target, 32768 /* Object */) && !(getObjectFlags(target) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
                    var isComparingJsxAttributes = !!(source.flags & 33554432 /* JsxAttributes */);
                    if ((relation === assignableRelation || relation === comparableRelation) &&
                        (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
                        return false;
                    }
                    if (target.flags & 65536 /* Union */) {
                        var discriminantType = findMatchingDiscriminantType(source, target);
                        if (discriminantType) {
                            // check excess properties against discriminant type only, not the entire union
                            return hasExcessProperties(source, discriminantType, reportErrors);
                        }
                    }
                    var _loop_4 = function (prop) {
                        if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
                            if (reportErrors) {
                                // We know *exactly* where things went wrong when comparing the types.
                                // Use this property as the error node as this will be more helpful in
                                // reasoning about what went wrong.
                                ts.Debug.assert(!!errorNode);
                                if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode)) {
                                    // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
                                    // However, using an object-literal error message will be very confusing to the users so we give different a message.
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target));
                                }
                                else {
                                    // use the property's value declaration if the property is assigned inside the literal itself
                                    var objectLiteralDeclaration_1 = source.symbol && ts.firstOrUndefined(source.symbol.declarations);
                                    var suggestion = void 0;
                                    if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, function (d) { return d === objectLiteralDeclaration_1; })) {
                                        var propDeclaration = prop.valueDeclaration;
                                        ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike);
                                        errorNode = propDeclaration;
                                        if (ts.isIdentifier(propDeclaration.name)) {
                                            suggestion = getSuggestionForNonexistentProperty(propDeclaration.name, target);
                                        }
                                    }
                                    if (suggestion !== undefined) {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(target), suggestion);
                                    }
                                    else {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target));
                                    }
                                }
                            }
                            return { value: true };
                        }
                    };
                    for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        var state_2 = _loop_4(prop);
                        if (typeof state_2 === "object")
                            return state_2.value;
                    }
                }
                return false;
            }
            function eachTypeRelatedToSomeType(source, target) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var _i = 0, sourceTypes_1 = sourceTypes; _i < sourceTypes_1.length; _i++) {
                    var sourceType = sourceTypes_1[_i];
                    var related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeRelatedToSomeType(source, target, reportErrors) {
                var targetTypes = target.types;
                if (target.flags & 65536 /* Union */ && containsType(targetTypes, source)) {
                    return -1 /* True */;
                }
                for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) {
                    var type = targetTypes_1[_i];
                    var related = isRelatedTo(source, type, /*reportErrors*/ false);
                    if (related) {
                        return related;
                    }
                }
                if (reportErrors) {
                    var discriminantType = findMatchingDiscriminantType(source, target);
                    isRelatedTo(source, discriminantType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
                }
                return 0 /* False */;
            }
            function findMatchingDiscriminantType(source, target) {
                var match;
                var sourceProperties = getPropertiesOfObjectType(source);
                if (sourceProperties) {
                    var sourceProperty = findSingleDiscriminantProperty(sourceProperties, target);
                    if (sourceProperty) {
                        var sourceType = getTypeOfSymbol(sourceProperty);
                        for (var _i = 0, _a = target.types; _i < _a.length; _i++) {
                            var type = _a[_i];
                            var targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName);
                            if (targetType && isRelatedTo(sourceType, targetType)) {
                                if (match) {
                                    return undefined;
                                }
                                match = type;
                            }
                        }
                    }
                }
                return match;
            }
            function typeRelatedToEachType(source, target, reportErrors) {
                var result = -1 /* True */;
                var targetTypes = target.types;
                for (var _i = 0, targetTypes_2 = targetTypes; _i < targetTypes_2.length; _i++) {
                    var targetType = targetTypes_2[_i];
                    var related = isRelatedTo(source, targetType, reportErrors);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function someTypeRelatedToType(source, target, reportErrors) {
                var sourceTypes = source.types;
                if (source.flags & 65536 /* Union */ && containsType(sourceTypes, target)) {
                    return -1 /* True */;
                }
                var len = sourceTypes.length;
                for (var i = 0; i < len; i++) {
                    var related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1);
                    if (related) {
                        return related;
                    }
                }
                return 0 /* False */;
            }
            function eachTypeRelatedToType(source, target, reportErrors) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var _i = 0, sourceTypes_2 = sourceTypes; _i < sourceTypes_2.length; _i++) {
                    var sourceType = sourceTypes_2[_i];
                    var related = isRelatedTo(sourceType, target, reportErrors);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeArgumentsRelatedTo(source, target, variances, reportErrors) {
                var sources = source.typeArguments || ts.emptyArray;
                var targets = target.typeArguments || ts.emptyArray;
                if (sources.length !== targets.length && relation === identityRelation) {
                    return 0 /* False */;
                }
                var length = sources.length <= targets.length ? sources.length : targets.length;
                var result = -1 /* True */;
                for (var i = 0; i < length; i++) {
                    // When variance information isn't available we default to covariance. This happens
                    // in the process of computing variance information for recursive types and when
                    // comparing 'this' type arguments.
                    var variance = i < variances.length ? variances[i] : 1 /* Covariant */;
                    // We ignore arguments for independent type parameters (because they're never witnessed).
                    if (variance !== 4 /* Independent */) {
                        var s = sources[i];
                        var t = targets[i];
                        var related = -1 /* True */;
                        if (variance === 1 /* Covariant */) {
                            related = isRelatedTo(s, t, reportErrors);
                        }
                        else if (variance === 2 /* Contravariant */) {
                            related = isRelatedTo(t, s, reportErrors);
                        }
                        else if (variance === 3 /* Bivariant */) {
                            // In the bivariant case we first compare contravariantly without reporting
                            // errors. Then, if that doesn't succeed, we compare covariantly with error
                            // reporting. Thus, error elaboration will be based on the the covariant check,
                            // which is generally easier to reason about.
                            related = isRelatedTo(t, s, /*reportErrors*/ false);
                            if (!related) {
                                related = isRelatedTo(s, t, reportErrors);
                            }
                        }
                        else {
                            // In the invariant case we first compare covariantly, and only when that
                            // succeeds do we proceed to compare contravariantly. Thus, error elaboration
                            // will typically be based on the covariant check.
                            related = isRelatedTo(s, t, reportErrors);
                            if (related) {
                                related &= isRelatedTo(t, s, reportErrors);
                            }
                        }
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            // Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
            // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
            // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
            // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
            // and issue an error. Otherwise, actually compare the structure of the two types.
            function recursiveTypeRelatedTo(source, target, reportErrors) {
                if (overflow) {
                    return 0 /* False */;
                }
                var id = getRelationKey(source, target, relation);
                var related = relation.get(id);
                if (related !== undefined) {
                    if (reportErrors && related === 2 /* Failed */) {
                        // We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
                        // failure and continue computing the relation such that errors get reported.
                        relation.set(id, 3 /* FailedAndReported */);
                    }
                    else {
                        return related === 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
                    }
                }
                if (!maybeKeys) {
                    maybeKeys = [];
                    sourceStack = [];
                    targetStack = [];
                }
                else {
                    for (var i = 0; i < maybeCount; i++) {
                        // If source and target are already being compared, consider them related with assumptions
                        if (id === maybeKeys[i]) {
                            return 1 /* Maybe */;
                        }
                    }
                    if (depth === 100) {
                        overflow = true;
                        return 0 /* False */;
                    }
                }
                var maybeStart = maybeCount;
                maybeKeys[maybeCount] = id;
                maybeCount++;
                sourceStack[depth] = source;
                targetStack[depth] = target;
                depth++;
                var saveExpandingFlags = expandingFlags;
                if (!(expandingFlags & 1 /* Source */) && isDeeplyNestedType(source, sourceStack, depth))
                    expandingFlags |= 1 /* Source */;
                if (!(expandingFlags & 2 /* Target */) && isDeeplyNestedType(target, targetStack, depth))
                    expandingFlags |= 2 /* Target */;
                var result = expandingFlags !== 3 /* Both */ ? structuredTypeRelatedTo(source, target, reportErrors) : 1 /* Maybe */;
                expandingFlags = saveExpandingFlags;
                depth--;
                if (result) {
                    if (result === -1 /* True */ || depth === 0) {
                        // If result is definitely true, record all maybe keys as having succeeded
                        for (var i = maybeStart; i < maybeCount; i++) {
                            relation.set(maybeKeys[i], 1 /* Succeeded */);
                        }
                        maybeCount = maybeStart;
                    }
                }
                else {
                    // A false result goes straight into global cache (when something is false under
                    // assumptions it will also be false without assumptions)
                    relation.set(id, reportErrors ? 3 /* FailedAndReported */ : 2 /* Failed */);
                    maybeCount = maybeStart;
                }
                return result;
            }
            function structuredTypeRelatedTo(source, target, reportErrors) {
                var result;
                var saveErrorInfo = errorInfo;
                if (target.flags & 16384 /* TypeParameter */) {
                    // A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P].
                    if (getObjectFlags(source) & 32 /* Mapped */ && getConstraintTypeFromMappedType(source) === getIndexType(target)) {
                        if (!source.declaration.questionToken) {
                            var templateType = getTemplateTypeFromMappedType(source);
                            var indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source));
                            if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) {
                                return result;
                            }
                        }
                    }
                }
                else if (target.flags & 262144 /* Index */) {
                    // A keyof S is related to a keyof T if T is related to S.
                    if (source.flags & 262144 /* Index */) {
                        if (result = isRelatedTo(target.type, source.type, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                    // A type S is assignable to keyof T if S is assignable to keyof C, where C is the
                    // constraint of T.
                    var constraint = getConstraintOfType(target.type);
                    if (constraint) {
                        if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) {
                            return result;
                        }
                    }
                }
                else if (target.flags & 524288 /* IndexedAccess */) {
                    // A type S is related to a type T[K] if S is related to A[K], where K is string-like and
                    // A is the apparent type of S.
                    var constraint = getConstraintOfIndexedAccess(target);
                    if (constraint) {
                        if (result = isRelatedTo(source, constraint, reportErrors)) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                }
                if (source.flags & 16384 /* TypeParameter */) {
                    // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
                    if (getObjectFlags(target) & 32 /* Mapped */ && getConstraintTypeFromMappedType(target) === getIndexType(source)) {
                        var indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target));
                        var templateType = getTemplateTypeFromMappedType(target);
                        if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                    else {
                        var constraint = getConstraintOfTypeParameter(source);
                        // A type parameter with no constraint is not related to the non-primitive object type.
                        if (constraint || !(target.flags & 16777216 /* NonPrimitive */)) {
                            if (!constraint || constraint.flags & 1 /* Any */) {
                                constraint = emptyObjectType;
                            }
                            // Report constraint errors only if the constraint is not the empty object type
                            var reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
                            if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                    }
                }
                else if (source.flags & 524288 /* IndexedAccess */) {
                    // A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
                    // A is the apparent type of S.
                    var constraint = getConstraintOfIndexedAccess(source);
                    if (constraint) {
                        if (result = isRelatedTo(constraint, target, reportErrors)) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                    else if (target.flags & 524288 /* IndexedAccess */ && source.indexType === target.indexType) {
                        // if we have indexed access types with identical index types, see if relationship holds for
                        // the two object types.
                        if (result = isRelatedTo(source.objectType, target.objectType, reportErrors)) {
                            return result;
                        }
                    }
                }
                else {
                    if (getObjectFlags(source) & 4 /* Reference */ && getObjectFlags(target) & 4 /* Reference */ && source.target === target.target &&
                        !(source.flags & 67108864 /* MarkerType */ || target.flags & 67108864 /* MarkerType */)) {
                        // We have type references to the same generic type, and the type references are not marker
                        // type references (which are intended by be compared structurally). Obtain the variance
                        // information for the type parameters and relate the type arguments accordingly.
                        var variances = getVariances(source.target);
                        if (result = typeArgumentsRelatedTo(source, target, variances, reportErrors)) {
                            return result;
                        }
                        // The type arguments did not relate appropriately, but it may be because we have no variance
                        // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
                        // arguments). It might also be the case that the target type has a 'void' type argument for
                        // a covariant type parameter that is only used in return positions within the generic type
                        // (in which case any type argument is permitted on the source side). In those cases we proceed
                        // with a structural comparison. Otherwise, we know for certain the instantiations aren't
                        // related and we can return here.
                        if (variances !== ts.emptyArray && !hasCovariantVoidArgument(target, variances)) {
                            // In some cases generic types that are covariant in regular type checking mode become
                            // invariant in --strictFunctionTypes mode because one or more type parameters are used in
                            // both co- and contravariant positions. In order to make it easier to diagnose *why* such
                            // types are invariant, if any of the type parameters are invariant we reset the reported
                            // errors and instead force a structural comparison (which will include elaborations that
                            // reveal the reason).
                            if (!(reportErrors && ts.some(variances, function (v) { return v === 0 /* Invariant */; }))) {
                                return 0 /* False */;
                            }
                            errorInfo = saveErrorInfo;
                        }
                    }
                    // Even if relationship doesn't hold for unions, intersections, or generic type references,
                    // it may hold in a structural comparison.
                    var sourceIsPrimitive = !!(source.flags & 8190 /* Primitive */);
                    if (relation !== identityRelation) {
                        source = getApparentType(source);
                    }
                    // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
                    // to X. Failing both of those we want to check if the aggregation of A and B's members structurally
                    // relates to X. Thus, we include intersection types on the source side here.
                    if (source.flags & (32768 /* Object */ | 131072 /* Intersection */) && target.flags & 32768 /* Object */) {
                        // Report structural errors only if we haven't reported any errors yet
                        var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !sourceIsPrimitive;
                        // An empty object type is related to any mapped type that includes a '?' modifier.
                        if (isPartialMappedType(target) && !isGenericMappedType(source) && isEmptyObjectType(source)) {
                            result = -1 /* True */;
                        }
                        else if (isGenericMappedType(target)) {
                            result = isGenericMappedType(source) ? mappedTypeRelatedTo(source, target, reportStructuralErrors) : 0 /* False */;
                        }
                        else {
                            result = propertiesRelatedTo(source, target, reportStructuralErrors);
                            if (result) {
                                result &= signaturesRelatedTo(source, target, 0 /* Call */, reportStructuralErrors);
                                if (result) {
                                    result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportStructuralErrors);
                                    if (result) {
                                        result &= indexTypesRelatedTo(source, target, 0 /* String */, sourceIsPrimitive, reportStructuralErrors);
                                        if (result) {
                                            result &= indexTypesRelatedTo(source, target, 1 /* Number */, sourceIsPrimitive, reportStructuralErrors);
                                        }
                                    }
                                }
                            }
                        }
                        if (result) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                }
                return 0 /* False */;
            }
            // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
            // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
            // that S and T are contra-variant whereas X and Y are co-variant.
            function mappedTypeRelatedTo(source, target, reportErrors) {
                var sourceReadonly = !!source.declaration.readonlyToken;
                var sourceOptional = !!source.declaration.questionToken;
                var targetReadonly = !!target.declaration.readonlyToken;
                var targetOptional = !!target.declaration.questionToken;
                var modifiersRelated = relation === identityRelation ?
                    sourceReadonly === targetReadonly && sourceOptional === targetOptional :
                    relation === comparableRelation || !sourceOptional || targetOptional;
                if (modifiersRelated) {
                    var result_2;
                    if (result_2 = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) {
                        var mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
                        return result_2 & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
                    }
                }
                return 0 /* False */;
            }
            function propertiesRelatedTo(source, target, reportErrors) {
                if (relation === identityRelation) {
                    return propertiesIdenticalTo(source, target);
                }
                var requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & 128 /* ObjectLiteral */);
                var unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
                if (unmatchedProperty) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), typeToString(source));
                    }
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                var properties = getPropertiesOfObjectType(target);
                for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
                    var targetProp = properties_3[_i];
                    if (!(targetProp.flags & 4194304 /* Prototype */)) {
                        var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                        if (sourceProp && sourceProp !== targetProp) {
                            var sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp);
                            var targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp);
                            if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) {
                                if (ts.getCheckFlags(sourceProp) & 256 /* ContainsPrivate */) {
                                    if (reportErrors) {
                                        reportError(ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source));
                                    }
                                    return 0 /* False */;
                                }
                                if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
                                    if (reportErrors) {
                                        if (sourcePropFlags & 8 /* Private */ && targetPropFlags & 8 /* Private */) {
                                            reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
                                        }
                                        else {
                                            reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & 8 /* Private */ ? source : target), typeToString(sourcePropFlags & 8 /* Private */ ? target : source));
                                        }
                                    }
                                    return 0 /* False */;
                                }
                            }
                            else if (targetPropFlags & 16 /* Protected */) {
                                if (!isValidOverrideOf(sourceProp, targetProp)) {
                                    if (reportErrors) {
                                        reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
                                    }
                                    return 0 /* False */;
                                }
                            }
                            else if (sourcePropFlags & 16 /* Protected */) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                                }
                                return 0 /* False */;
                            }
                            var related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors);
                            if (!related) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
                                }
                                return 0 /* False */;
                            }
                            result &= related;
                            // When checking for comparability, be more lenient with optional properties.
                            if (relation !== comparableRelation && sourceProp.flags & 16777216 /* Optional */ && !(targetProp.flags & 16777216 /* Optional */)) {
                                // TypeScript 1.0 spec (April 2014): 3.8.3
                                // S is a subtype of a type T, and T is a supertype of S if ...
                                // S' and T are object types and, for each member M in T..
                                // M is a property and S' contains a property N where
                                // if M is a required property, N is also a required property
                                // (M - property in T)
                                // (N - property in S)
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                                }
                                return 0 /* False */;
                            }
                        }
                    }
                }
                return result;
            }
            /**
             * A type is 'weak' if it is an object type with at least one optional property
             * and no required properties, call/construct signatures or index signatures
             */
            function isWeakType(type) {
                if (type.flags & 32768 /* Object */) {
                    var resolved = resolveStructuredTypeMembers(type);
                    return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 &&
                        !resolved.stringIndexInfo && !resolved.numberIndexInfo &&
                        resolved.properties.length > 0 &&
                        ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216 /* Optional */); });
                }
                if (type.flags & 131072 /* Intersection */) {
                    return ts.every(type.types, isWeakType);
                }
                return false;
            }
            function hasCommonProperties(source, target) {
                var isComparingJsxAttributes = !!(source.flags & 33554432 /* JsxAttributes */);
                for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
                        return true;
                    }
                }
                return false;
            }
            function propertiesIdenticalTo(source, target) {
                if (!(source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */)) {
                    return 0 /* False */;
                }
                var sourceProperties = getPropertiesOfObjectType(source);
                var targetProperties = getPropertiesOfObjectType(target);
                if (sourceProperties.length !== targetProperties.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var _i = 0, sourceProperties_1 = sourceProperties; _i < sourceProperties_1.length; _i++) {
                    var sourceProp = sourceProperties_1[_i];
                    var targetProp = getPropertyOfObjectType(target, sourceProp.escapedName);
                    if (!targetProp) {
                        return 0 /* False */;
                    }
                    var related = compareProperties(sourceProp, targetProp, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function signaturesRelatedTo(source, target, kind, reportErrors) {
                if (relation === identityRelation) {
                    return signaturesIdenticalTo(source, target, kind);
                }
                if (target === anyFunctionType || source === anyFunctionType) {
                    return -1 /* True */;
                }
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                if (kind === 1 /* Construct */ && sourceSignatures.length && targetSignatures.length) {
                    if (isAbstractConstructorType(source) && !isAbstractConstructorType(target)) {
                        // An abstract constructor type is not assignable to a non-abstract constructor type
                        // as it would otherwise be possible to new an abstract class. Note that the assignability
                        // check we perform for an extends clause excludes construct signatures from the target,
                        // so this check never proceeds.
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
                        }
                        return 0 /* False */;
                    }
                    if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) {
                        return 0 /* False */;
                    }
                }
                var result = -1 /* True */;
                var saveErrorInfo = errorInfo;
                if (getObjectFlags(source) & 64 /* Instantiated */ && getObjectFlags(target) & 64 /* Instantiated */ && source.symbol === target.symbol) {
                    // We have instantiations of the same anonymous type (which typically will be the type of a
                    // method). Simply do a pairwise comparison of the signatures in the two signature lists instead
                    // of the much more expensive N * M comparison matrix we explore below. We erase type parameters
                    // as they are known to always be the same.
                    for (var i = 0; i < targetSignatures.length; i++) {
                        var related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
                    // For simple functions (functions with a single signature) we only erase type parameters for
                    // the comparable relation. Otherwise, if the source signature is generic, we instantiate it
                    // in the context of the target signature before checking the relationship. Ideally we'd do
                    // this regardless of the number of signatures, but the potential costs are prohibitive due
                    // to the quadratic nature of the logic below.
                    var eraseGenerics = relation === comparableRelation || compilerOptions.noStrictGenericChecks;
                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors);
                }
                else {
                    outer: for (var _i = 0, targetSignatures_1 = targetSignatures; _i < targetSignatures_1.length; _i++) {
                        var t = targetSignatures_1[_i];
                        // Only elaborate errors from the first failure
                        var shouldElaborateErrors = reportErrors;
                        for (var _a = 0, sourceSignatures_1 = sourceSignatures; _a < sourceSignatures_1.length; _a++) {
                            var s = sourceSignatures_1[_a];
                            var related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors);
                            if (related) {
                                result &= related;
                                errorInfo = saveErrorInfo;
                                continue outer;
                            }
                            shouldElaborateErrors = false;
                        }
                        if (shouldElaborateErrors) {
                            reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind));
                        }
                        return 0 /* False */;
                    }
                }
                return result;
            }
            /**
             * See signatureAssignableTo, compareSignaturesIdentical
             */
            function signatureRelatedTo(source, target, erase, reportErrors) {
                return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, 0 /* None */, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
            }
            function signaturesIdenticalTo(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                if (sourceSignatures.length !== targetSignatures.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var i = 0; i < sourceSignatures.length; i++) {
                    var related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function eachPropertyRelatedTo(source, target, kind, reportErrors) {
                var result = -1 /* True */;
                for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        var related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors);
                        if (!related) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop));
                            }
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            function indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors) {
                var related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors);
                if (!related && reportErrors) {
                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
                }
                return related;
            }
            function indexTypesRelatedTo(source, target, kind, sourceIsPrimitive, reportErrors) {
                if (relation === identityRelation) {
                    return indexTypesIdenticalTo(source, target, kind);
                }
                var targetInfo = getIndexInfoOfType(target, kind);
                if (!targetInfo || targetInfo.type.flags & 1 /* Any */ && !sourceIsPrimitive) {
                    // Index signature of type any permits assignment from everything but primitives
                    return -1 /* True */;
                }
                var sourceInfo = getIndexInfoOfType(source, kind) ||
                    kind === 1 /* Number */ && getIndexInfoOfType(source, 0 /* String */);
                if (sourceInfo) {
                    return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors);
                }
                if (isGenericMappedType(source)) {
                    // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U }
                    // if T is related to U.
                    return kind === 0 /* String */ && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors);
                }
                if (isObjectTypeWithInferableIndex(source)) {
                    var related = -1 /* True */;
                    if (kind === 0 /* String */) {
                        var sourceNumberInfo = getIndexInfoOfType(source, 1 /* Number */);
                        if (sourceNumberInfo) {
                            related = indexInfoRelatedTo(sourceNumberInfo, targetInfo, reportErrors);
                        }
                    }
                    if (related) {
                        related &= eachPropertyRelatedTo(source, targetInfo.type, kind, reportErrors);
                    }
                    return related;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
                }
                return 0 /* False */;
            }
            function indexTypesIdenticalTo(source, target, indexKind) {
                var targetInfo = getIndexInfoOfType(target, indexKind);
                var sourceInfo = getIndexInfoOfType(source, indexKind);
                if (!sourceInfo && !targetInfo) {
                    return -1 /* True */;
                }
                if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) {
                    return isRelatedTo(sourceInfo.type, targetInfo.type);
                }
                return 0 /* False */;
            }
            function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) {
                if (!sourceSignature.declaration || !targetSignature.declaration) {
                    return true;
                }
                var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                // A public, protected and private signature is assignable to a private signature.
                if (targetAccessibility === 8 /* Private */) {
                    return true;
                }
                // A public and protected signature is assignable to a protected signature.
                if (targetAccessibility === 16 /* Protected */ && sourceAccessibility !== 8 /* Private */) {
                    return true;
                }
                // Only a public signature is assignable to public signature.
                if (targetAccessibility !== 16 /* Protected */ && !sourceAccessibility) {
                    return true;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility));
                }
                return false;
            }
        }
        // Return a type reference where the source type parameter is replaced with the target marker
        // type, and flag the result as a marker type reference.
        function getMarkerTypeReference(type, source, target) {
            var result = createTypeReference(type, ts.map(type.typeParameters, function (t) { return t === source ? target : t; }));
            result.flags |= 67108864 /* MarkerType */;
            return result;
        }
        // Return an array containing the variance of each type parameter. The variance is effectively
        // a digest of the type comparisons that occur for each type argument when instantiations of the
        // generic type are structurally compared. We infer the variance information by comparing
        // instantiations of the generic type for type arguments with known relations. The function
        // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function
        // has been invoked recursively for the given generic type.
        function getVariances(type) {
            if (!strictFunctionTypes) {
                return ts.emptyArray;
            }
            var typeParameters = type.typeParameters || ts.emptyArray;
            var variances = type.variances;
            if (!variances) {
                if (type === globalArrayType || type === globalReadonlyArrayType) {
                    // Arrays are known to be covariant, no need to spend time computing this
                    variances = [1 /* Covariant */];
                }
                else {
                    // The emptyArray singleton is used to signal a recursive invocation.
                    type.variances = ts.emptyArray;
                    variances = [];
                    for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) {
                        var tp = typeParameters_1[_i];
                        // We first compare instantiations where the type parameter is replaced with
                        // marker types that have a known subtype relationship. From this we can infer
                        // invariance, covariance, contravariance or bivariance.
                        var typeWithSuper = getMarkerTypeReference(type, tp, markerSuperType);
                        var typeWithSub = getMarkerTypeReference(type, tp, markerSubType);
                        var variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? 1 /* Covariant */ : 0) |
                            (isTypeAssignableTo(typeWithSuper, typeWithSub) ? 2 /* Contravariant */ : 0);
                        // If the instantiations appear to be related bivariantly it may be because the
                        // type parameter is independent (i.e. it isn't witnessed anywhere in the generic
                        // type). To determine this we compare instantiations where the type parameter is
                        // replaced with marker types that are known to be unrelated.
                        if (variance === 3 /* Bivariant */ && isTypeAssignableTo(getMarkerTypeReference(type, tp, markerOtherType), typeWithSuper)) {
                            variance = 4 /* Independent */;
                        }
                        variances.push(variance);
                    }
                }
                type.variances = variances;
            }
            return variances;
        }
        // Return true if the given type reference has a 'void' type argument for a covariant type parameter.
        // See comment at call in recursiveTypeRelatedTo for when this case matters.
        function hasCovariantVoidArgument(type, variances) {
            for (var i = 0; i < variances.length; i++) {
                if (variances[i] === 1 /* Covariant */ && type.typeArguments[i].flags & 1024 /* Void */) {
                    return true;
                }
            }
            return false;
        }
        function isUnconstrainedTypeParameter(type) {
            return type.flags & 16384 /* TypeParameter */ && !getConstraintFromTypeParameter(type);
        }
        function isTypeReferenceWithGenericArguments(type) {
            return getObjectFlags(type) & 4 /* Reference */ && ts.some(type.typeArguments, function (t) { return isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t); });
        }
        /**
         * getTypeReferenceId(A<T, number, U>) returns "111=0-12=1"
         *   where A.id=111 and number.id=12
         */
        function getTypeReferenceId(type, typeParameters, depth) {
            if (depth === void 0) { depth = 0; }
            var result = "" + type.target.id;
            for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) {
                var t = _a[_i];
                if (isUnconstrainedTypeParameter(t)) {
                    var index = ts.indexOf(typeParameters, t);
                    if (index < 0) {
                        index = typeParameters.length;
                        typeParameters.push(t);
                    }
                    result += "=" + index;
                }
                else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) {
                    result += "<" + getTypeReferenceId(t, typeParameters, depth + 1) + ">";
                }
                else {
                    result += "-" + t.id;
                }
            }
            return result;
        }
        /**
         * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters.
         * For other cases, the types ids are used.
         */
        function getRelationKey(source, target, relation) {
            if (relation === identityRelation && source.id > target.id) {
                var temp = source;
                source = target;
                target = temp;
            }
            if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) {
                var typeParameters = [];
                return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters);
            }
            return source.id + "," + target.id;
        }
        // Invoke the callback for each underlying property symbol of the given symbol and return the first
        // value that isn't undefined.
        function forEachProperty(prop, callback) {
            if (ts.getCheckFlags(prop) & 6 /* Synthetic */) {
                for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var p = getPropertyOfType(t, prop.escapedName);
                    var result = p && forEachProperty(p, callback);
                    if (result) {
                        return result;
                    }
                }
                return undefined;
            }
            return callback(prop);
        }
        // Return the declaring class type of a property or undefined if property not declared in class
        function getDeclaringClass(prop) {
            return prop.parent && prop.parent.flags & 32 /* Class */ ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)) : undefined;
        }
        // Return true if some underlying source property is declared in a class that derives
        // from the given base class.
        function isPropertyInClassDerivedFrom(prop, baseClass) {
            return forEachProperty(prop, function (sp) {
                var sourceClass = getDeclaringClass(sp);
                return sourceClass ? hasBaseType(sourceClass, baseClass) : false;
            });
        }
        // Return true if source property is a valid override of protected parts of target property.
        function isValidOverrideOf(sourceProp, targetProp) {
            return !forEachProperty(targetProp, function (tp) { return ts.getDeclarationModifierFlagsFromSymbol(tp) & 16 /* Protected */ ?
                !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false; });
        }
        // Return true if the given class derives from each of the declaring classes of the protected
        // constituents of the given property.
        function isClassDerivedFromDeclaringClasses(checkClass, prop) {
            return forEachProperty(prop, function (p) { return ts.getDeclarationModifierFlagsFromSymbol(p) & 16 /* Protected */ ?
                !hasBaseType(checkClass, getDeclaringClass(p)) : false; }) ? undefined : checkClass;
        }
        // Return true if the given type is the constructor type for an abstract class
        function isAbstractConstructorType(type) {
            if (getObjectFlags(type) & 16 /* Anonymous */) {
                var symbol = type.symbol;
                if (symbol && symbol.flags & 32 /* Class */) {
                    var declaration = getClassLikeDeclarationOfSymbol(symbol);
                    if (declaration && ts.hasModifier(declaration, 128 /* Abstract */)) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
        // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
        // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
        // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5
        // levels, but unequal at some level beyond that.
        function isDeeplyNestedType(type, stack, depth) {
            // We track all object types that have an associated symbol (representing the origin of the type)
            if (depth >= 5 && type.flags & 32768 /* Object */) {
                var symbol = type.symbol;
                if (symbol) {
                    var count = 0;
                    for (var i = 0; i < depth; i++) {
                        var t = stack[i];
                        if (t.flags & 32768 /* Object */ && t.symbol === symbol) {
                            count++;
                            if (count >= 5)
                                return true;
                        }
                    }
                }
            }
            return false;
        }
        function isPropertyIdenticalTo(sourceProp, targetProp) {
            return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== 0 /* False */;
        }
        function compareProperties(sourceProp, targetProp, compareTypes) {
            // Two members are considered identical when
            // - they are public properties with identical names, optionality, and types,
            // - they are private or protected properties originating in the same declaration and having identical types
            if (sourceProp === targetProp) {
                return -1 /* True */;
            }
            var sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & 24 /* NonPublicAccessibilityModifier */;
            var targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & 24 /* NonPublicAccessibilityModifier */;
            if (sourcePropAccessibility !== targetPropAccessibility) {
                return 0 /* False */;
            }
            if (sourcePropAccessibility) {
                if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
                    return 0 /* False */;
                }
            }
            else {
                if ((sourceProp.flags & 16777216 /* Optional */) !== (targetProp.flags & 16777216 /* Optional */)) {
                    return 0 /* False */;
                }
            }
            if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) {
                return 0 /* False */;
            }
            return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
        }
        function isMatchingSignature(source, target, partialMatch) {
            // A source signature matches a target signature if the two signatures have the same number of required,
            // optional, and rest parameters.
            if (source.parameters.length === target.parameters.length &&
                source.minArgumentCount === target.minArgumentCount &&
                source.hasRestParameter === target.hasRestParameter) {
                return true;
            }
            // A source signature partially matches a target signature if the target signature has no fewer required
            // parameters and no more overall parameters than the source signature (where a signature with a rest
            // parameter is always considered to have more overall parameters than one without).
            var sourceRestCount = source.hasRestParameter ? 1 : 0;
            var targetRestCount = target.hasRestParameter ? 1 : 0;
            if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (sourceRestCount > targetRestCount ||
                sourceRestCount === targetRestCount && source.parameters.length >= target.parameters.length)) {
                return true;
            }
            return false;
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesIdentical(source, target, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypes) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (!(isMatchingSignature(source, target, partialMatch))) {
                return 0 /* False */;
            }
            // Check that the two signatures have the same number of type parameters. We might consider
            // also checking that any type parameter constraints match, but that would require instantiating
            // the constraints with a common set of type arguments to get relatable entities in places where
            // type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
            // particularly as we're comparing erased versions of the signatures below.
            if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) {
                return 0 /* False */;
            }
            // Spec 1.0 Section 3.8.3 & 3.8.4:
            // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
            source = getErasedSignature(source);
            target = getErasedSignature(target);
            var result = -1 /* True */;
            if (!ignoreThisTypes) {
                var sourceThisType = getThisTypeOfSignature(source);
                if (sourceThisType) {
                    var targetThisType = getThisTypeOfSignature(target);
                    if (targetThisType) {
                        var related = compareTypes(sourceThisType, targetThisType);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
            }
            var targetLen = target.parameters.length;
            for (var i = 0; i < targetLen; i++) {
                var s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfParameter(source.parameters[i]);
                var t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfParameter(target.parameters[i]);
                var related = compareTypes(s, t);
                if (!related) {
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!ignoreReturnTypes) {
                result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
            return result;
        }
        function isRestParameterIndex(signature, parameterIndex) {
            return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1;
        }
        function literalTypesWithSameBaseType(types) {
            var commonBaseType;
            for (var _i = 0, types_10 = types; _i < types_10.length; _i++) {
                var t = types_10[_i];
                var baseType = getBaseTypeOfLiteralType(t);
                if (!commonBaseType) {
                    commonBaseType = baseType;
                }
                if (baseType === t || baseType !== commonBaseType) {
                    return false;
                }
            }
            return true;
        }
        // When the candidate types are all literal types with the same base type, return a union
        // of those literal types. Otherwise, return the leftmost type for which no type to the
        // right is a supertype.
        function getSupertypeOrUnion(types) {
            return literalTypesWithSameBaseType(types) ?
                getUnionType(types) :
                ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(s, t) ? t : s; });
        }
        function getCommonSupertype(types) {
            if (!strictNullChecks) {
                return getSupertypeOrUnion(types);
            }
            var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 6144 /* Nullable */); });
            return primaryTypes.length ?
                getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & 6144 /* Nullable */) :
                getUnionType(types, /*subtypeReduction*/ true);
        }
        // Return the leftmost type for which no type to the right is a subtype.
        function getCommonSubtype(types) {
            return ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(t, s) ? t : s; });
        }
        function isArrayType(type) {
            return getObjectFlags(type) & 4 /* Reference */ && type.target === globalArrayType;
        }
        function isArrayLikeType(type) {
            // A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
            // or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
            return getObjectFlags(type) & 4 /* Reference */ && (type.target === globalArrayType || type.target === globalReadonlyArrayType) ||
                !(type.flags & 6144 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType);
        }
        function isTupleLikeType(type) {
            return !!getPropertyOfType(type, "0");
        }
        function isUnitType(type) {
            return !!(type.flags & 6368 /* Unit */);
        }
        function isLiteralType(type) {
            return type.flags & 8 /* Boolean */ ? true :
                type.flags & 65536 /* Union */ ? type.flags & 256 /* EnumLiteral */ ? true : !ts.forEach(type.types, function (t) { return !isUnitType(t); }) :
                    isUnitType(type);
        }
        function getBaseTypeOfLiteralType(type) {
            return type.flags & 256 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 32 /* StringLiteral */ ? stringType :
                    type.flags & 64 /* NumberLiteral */ ? numberType :
                        type.flags & 128 /* BooleanLiteral */ ? booleanType :
                            type.flags & 65536 /* Union */ ? getUnionType(ts.sameMap(type.types, getBaseTypeOfLiteralType)) :
                                type;
        }
        function getWidenedLiteralType(type) {
            return type.flags & 256 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 32 /* StringLiteral */ && type.flags & 1048576 /* FreshLiteral */ ? stringType :
                    type.flags & 64 /* NumberLiteral */ && type.flags & 1048576 /* FreshLiteral */ ? numberType :
                        type.flags & 128 /* BooleanLiteral */ ? booleanType :
                            type.flags & 65536 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedLiteralType)) :
                                type;
        }
        /**
         * Check if a Type was written as a tuple type literal.
         * Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
         */
        function isTupleType(type) {
            return !!(getObjectFlags(type) & 4 /* Reference */ && type.target.objectFlags & 8 /* Tuple */);
        }
        function getFalsyFlagsOfTypes(types) {
            var result = 0;
            for (var _i = 0, types_11 = types; _i < types_11.length; _i++) {
                var t = types_11[_i];
                result |= getFalsyFlags(t);
            }
            return result;
        }
        // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null
        // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns
        // no flags for all other types (including non-falsy literal types).
        function getFalsyFlags(type) {
            return type.flags & 65536 /* Union */ ? getFalsyFlagsOfTypes(type.types) :
                type.flags & 32 /* StringLiteral */ ? type.value === "" ? 32 /* StringLiteral */ : 0 :
                    type.flags & 64 /* NumberLiteral */ ? type.value === 0 ? 64 /* NumberLiteral */ : 0 :
                        type.flags & 128 /* BooleanLiteral */ ? type === falseType ? 128 /* BooleanLiteral */ : 0 :
                            type.flags & 7406 /* PossiblyFalsy */;
        }
        function removeDefinitelyFalsyTypes(type) {
            return getFalsyFlags(type) & 7392 /* DefinitelyFalsy */ ?
                filterType(type, function (t) { return !(getFalsyFlags(t) & 7392 /* DefinitelyFalsy */); }) :
                type;
        }
        function extractDefinitelyFalsyTypes(type) {
            return mapType(type, getDefinitelyFalsyPartOfType);
        }
        function getDefinitelyFalsyPartOfType(type) {
            return type.flags & 2 /* String */ ? emptyStringType :
                type.flags & 4 /* Number */ ? zeroType :
                    type.flags & 8 /* Boolean */ || type === falseType ? falseType :
                        type.flags & (1024 /* Void */ | 2048 /* Undefined */ | 4096 /* Null */) ||
                            type.flags & 32 /* StringLiteral */ && type.value === "" ||
                            type.flags & 64 /* NumberLiteral */ && type.value === 0 ? type :
                            neverType;
        }
        /**
         * Add undefined or null or both to a type if they are missing.
         * @param type - type to add undefined and/or null to if not present
         * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both
         */
        function getNullableType(type, flags) {
            var missing = (flags & ~type.flags) & (2048 /* Undefined */ | 4096 /* Null */);
            return missing === 0 ? type :
                missing === 2048 /* Undefined */ ? getUnionType([type, undefinedType]) :
                    missing === 4096 /* Null */ ? getUnionType([type, nullType]) :
                        getUnionType([type, undefinedType, nullType]);
        }
        function getNonNullableType(type) {
            return strictNullChecks ? getTypeWithFacts(type, 524288 /* NEUndefinedOrNull */) : type;
        }
        /**
         * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
         * with no call or construct signatures.
         */
        function isObjectTypeWithInferableIndex(type) {
            return type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */ | 512 /* ValueModule */)) !== 0 &&
                getSignaturesOfType(type, 0 /* Call */).length === 0 &&
                getSignaturesOfType(type, 1 /* Construct */).length === 0;
        }
        function createSymbolWithType(source, type) {
            var symbol = createSymbol(source.flags, source.escapedName);
            symbol.declarations = source.declarations;
            symbol.parent = source.parent;
            symbol.type = type;
            symbol.target = source;
            if (source.valueDeclaration) {
                symbol.valueDeclaration = source.valueDeclaration;
            }
            return symbol;
        }
        function transformTypeOfMembers(type, f) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var property = _a[_i];
                var original = getTypeOfSymbol(property);
                var updated = f(original);
                members.set(property.escapedName, updated === original ? property : createSymbolWithType(property, updated));
            }
            return members;
        }
        /**
         * If the the provided object literal is subject to the excess properties check,
         * create a new that is exempt. Recursively mark object literal members as exempt.
         * Leave signatures alone since they are not subject to the check.
         */
        function getRegularTypeOfObjectLiteral(type) {
            if (!(getObjectFlags(type) & 128 /* ObjectLiteral */ && type.flags & 1048576 /* FreshLiteral */)) {
                return type;
            }
            var regularType = type.regularType;
            if (regularType) {
                return regularType;
            }
            var resolved = type;
            var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral);
            var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo);
            regularNew.flags = resolved.flags & ~1048576 /* FreshLiteral */;
            regularNew.objectFlags |= 128 /* ObjectLiteral */;
            type.regularType = regularNew;
            return regularNew;
        }
        function getWidenedProperty(prop) {
            var original = getTypeOfSymbol(prop);
            var widened = getWidenedType(original);
            return widened === original ? prop : createSymbolWithType(prop, widened);
        }
        function getWidenedTypeOfObjectLiteral(type) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var prop = _a[_i];
                // Since get accessors already widen their return value there is no need to
                // widen accessor based properties here.
                members.set(prop.escapedName, prop.flags & 4 /* Property */ ? getWidenedProperty(prop) : prop);
            }
            var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            return createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
        }
        function getWidenedConstituentType(type) {
            return type.flags & 6144 /* Nullable */ ? type : getWidenedType(type);
        }
        function getWidenedType(type) {
            if (type.flags & 6291456 /* RequiresWidening */) {
                if (type.flags & 6144 /* Nullable */) {
                    return anyType;
                }
                if (getObjectFlags(type) & 128 /* ObjectLiteral */) {
                    return getWidenedTypeOfObjectLiteral(type);
                }
                if (type.flags & 65536 /* Union */) {
                    return getUnionType(ts.sameMap(type.types, getWidenedConstituentType));
                }
                if (isArrayType(type) || isTupleType(type)) {
                    return createTypeReference(type.target, ts.sameMap(type.typeArguments, getWidenedType));
                }
            }
            return type;
        }
        /**
         * Reports implicit any errors that occur as a result of widening 'null' and 'undefined'
         * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to
         * getWidenedType. But in some cases getWidenedType is called without reporting errors
         * (type argument inference is an example).
         *
         * The return value indicates whether an error was in fact reported. The particular circumstances
         * are on a best effort basis. Currently, if the null or undefined that causes widening is inside
         * an object literal property (arbitrarily deeply), this function reports an error. If no error is
         * reported, reportImplicitAnyError is a suitable fallback to report a general error.
         */
        function reportWideningErrorsInType(type) {
            var errorReported = false;
            if (type.flags & 65536 /* Union */) {
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (reportWideningErrorsInType(t)) {
                        errorReported = true;
                    }
                }
            }
            if (isArrayType(type) || isTupleType(type)) {
                for (var _b = 0, _c = type.typeArguments; _b < _c.length; _b++) {
                    var t = _c[_b];
                    if (reportWideningErrorsInType(t)) {
                        errorReported = true;
                    }
                }
            }
            if (getObjectFlags(type) & 128 /* ObjectLiteral */) {
                for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) {
                    var p = _e[_d];
                    var t = getTypeOfSymbol(p);
                    if (t.flags & 2097152 /* ContainsWideningType */) {
                        if (!reportWideningErrorsInType(t)) {
                            error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, ts.symbolName(p), typeToString(getWidenedType(t)));
                        }
                        errorReported = true;
                    }
                }
            }
            return errorReported;
        }
        function reportImplicitAnyError(declaration, type) {
            var typeAsString = typeToString(getWidenedType(type));
            var diagnostic;
            switch (declaration.kind) {
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    diagnostic = ts.Diagnostics.Member_0_implicitly_has_an_1_type;
                    break;
                case 146 /* Parameter */:
                    diagnostic = declaration.dotDotDotToken ?
                        ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type :
                        ts.Diagnostics.Parameter_0_implicitly_has_an_1_type;
                    break;
                case 176 /* BindingElement */:
                    diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type;
                    break;
                case 228 /* FunctionDeclaration */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    if (!declaration.name) {
                        error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                        return;
                    }
                    diagnostic = ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type;
                    break;
                default:
                    diagnostic = ts.Diagnostics.Variable_0_implicitly_has_an_1_type;
            }
            error(declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString);
        }
        function reportErrorsFromWidening(declaration, type) {
            if (produceDiagnostics && noImplicitAny && type.flags & 2097152 /* ContainsWideningType */) {
                // Report implicit any error within type if possible, otherwise report error on declaration
                if (!reportWideningErrorsInType(type)) {
                    reportImplicitAnyError(declaration, type);
                }
            }
        }
        function forEachMatchingParameterType(source, target, callback) {
            var sourceMax = source.parameters.length;
            var targetMax = target.parameters.length;
            var count;
            if (source.hasRestParameter && target.hasRestParameter) {
                count = Math.max(sourceMax, targetMax);
            }
            else if (source.hasRestParameter) {
                count = targetMax;
            }
            else if (target.hasRestParameter) {
                count = sourceMax;
            }
            else {
                count = Math.min(sourceMax, targetMax);
            }
            for (var i = 0; i < count; i++) {
                callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
            }
        }
        function createInferenceContext(signature, flags, compareTypes, baseInferences) {
            var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo);
            var context = mapper;
            context.signature = signature;
            context.inferences = inferences;
            context.flags = flags;
            context.compareTypes = compareTypes || compareTypesAssignable;
            return context;
            function mapper(t) {
                for (var i = 0; i < inferences.length; i++) {
                    if (t === inferences[i].typeParameter) {
                        inferences[i].isFixed = true;
                        return getInferredType(context, i);
                    }
                }
                return t;
            }
        }
        function createInferenceInfo(typeParameter) {
            return {
                typeParameter: typeParameter,
                candidates: undefined,
                inferredType: undefined,
                priority: undefined,
                topLevel: true,
                isFixed: false
            };
        }
        function cloneInferenceInfo(inference) {
            return {
                typeParameter: inference.typeParameter,
                candidates: inference.candidates && inference.candidates.slice(),
                inferredType: inference.inferredType,
                priority: inference.priority,
                topLevel: inference.topLevel,
                isFixed: inference.isFixed
            };
        }
        // Return true if the given type could possibly reference a type parameter for which
        // we perform type inference (i.e. a type parameter of a generic function). We cache
        // results for union and intersection types for performance reasons.
        function couldContainTypeVariables(type) {
            var objectFlags = getObjectFlags(type);
            return !!(type.flags & (540672 /* TypeVariable */ | 262144 /* Index */) ||
                objectFlags & 4 /* Reference */ && ts.forEach(type.typeArguments, couldContainTypeVariables) ||
                objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */) ||
                objectFlags & 32 /* Mapped */ ||
                type.flags & 196608 /* UnionOrIntersection */ && couldUnionOrIntersectionContainTypeVariables(type));
        }
        function couldUnionOrIntersectionContainTypeVariables(type) {
            if (type.couldContainTypeVariables === undefined) {
                type.couldContainTypeVariables = ts.forEach(type.types, couldContainTypeVariables);
            }
            return type.couldContainTypeVariables;
        }
        function isTypeParameterAtTopLevel(type, typeParameter) {
            return type === typeParameter || type.flags & 196608 /* UnionOrIntersection */ && ts.forEach(type.types, function (t) { return isTypeParameterAtTopLevel(t, typeParameter); });
        }
        // Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct
        // an object type with the same set of properties as the source type, where the type of each
        // property is computed by inferring from the source property type to X for the type
        // variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
        function inferTypeForHomomorphicMappedType(source, target) {
            var properties = getPropertiesOfType(source);
            var indexInfo = getIndexInfoOfType(source, 0 /* String */);
            if (properties.length === 0 && !indexInfo) {
                return undefined;
            }
            var typeParameter = getIndexedAccessType(getConstraintTypeFromMappedType(target).type, getTypeParameterFromMappedType(target));
            var inference = createInferenceInfo(typeParameter);
            var inferences = [inference];
            var templateType = getTemplateTypeFromMappedType(target);
            var readonlyMask = target.declaration.readonlyToken ? false : true;
            var optionalMask = target.declaration.questionToken ? 0 : 16777216 /* Optional */;
            var members = ts.createSymbolTable();
            for (var _i = 0, properties_4 = properties; _i < properties_4.length; _i++) {
                var prop = properties_4[_i];
                var inferredPropType = inferTargetType(getTypeOfSymbol(prop));
                if (!inferredPropType) {
                    return undefined;
                }
                var inferredProp = createSymbol(4 /* Property */ | prop.flags & optionalMask, prop.escapedName);
                inferredProp.checkFlags = readonlyMask && isReadonlySymbol(prop) ? 8 /* Readonly */ : 0;
                inferredProp.declarations = prop.declarations;
                inferredProp.type = inferredPropType;
                members.set(prop.escapedName, inferredProp);
            }
            if (indexInfo) {
                var inferredIndexType = inferTargetType(indexInfo.type);
                if (!inferredIndexType) {
                    return undefined;
                }
                indexInfo = createIndexInfo(inferredIndexType, readonlyMask && indexInfo.isReadonly);
            }
            return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined);
            function inferTargetType(sourceType) {
                inference.candidates = undefined;
                inferTypes(inferences, sourceType, templateType);
                return inference.candidates && getUnionType(inference.candidates, /*subtypeReduction*/ true);
            }
        }
        function getUnmatchedProperty(source, target, requireOptionalProperties) {
            var properties = getPropertiesOfObjectType(target);
            for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) {
                var targetProp = properties_5[_i];
                if (requireOptionalProperties || !(targetProp.flags & 16777216 /* Optional */)) {
                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                    if (!sourceProp) {
                        return targetProp;
                    }
                }
            }
            return undefined;
        }
        function inferTypes(inferences, originalSource, originalTarget, priority) {
            if (priority === void 0) { priority = 0; }
            var symbolStack;
            var visited;
            inferFromTypes(originalSource, originalTarget);
            function inferFromTypes(source, target) {
                if (!couldContainTypeVariables(target)) {
                    return;
                }
                if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
                    // Source and target are types originating in the same generic type alias declaration.
                    // Simply infer from source type arguments to target type arguments.
                    var sourceTypes = source.aliasTypeArguments;
                    var targetTypes = target.aliasTypeArguments;
                    for (var i = 0; i < sourceTypes.length; i++) {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                    return;
                }
                if (source.flags & 65536 /* Union */ && target.flags & 65536 /* Union */ && !(source.flags & 256 /* EnumLiteral */ && target.flags & 256 /* EnumLiteral */) ||
                    source.flags & 131072 /* Intersection */ && target.flags & 131072 /* Intersection */) {
                    // Source and target are both unions or both intersections. If source and target
                    // are the same type, just relate each constituent type to itself.
                    if (source === target) {
                        for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                            var t = _a[_i];
                            inferFromTypes(t, t);
                        }
                        return;
                    }
                    // Find each source constituent type that has an identically matching target constituent
                    // type, and for each such type infer from the type to itself. When inferring from a
                    // type to itself we effectively find all type parameter occurrences within that type
                    // and infer themselves as their type arguments. We have special handling for numeric
                    // and string literals because the number and string types are not represented as unions
                    // of all their possible values.
                    var matchingTypes = void 0;
                    for (var _b = 0, _c = source.types; _b < _c.length; _b++) {
                        var t = _c[_b];
                        if (typeIdenticalToSomeType(t, target.types)) {
                            (matchingTypes || (matchingTypes = [])).push(t);
                            inferFromTypes(t, t);
                        }
                        else if (t.flags & (64 /* NumberLiteral */ | 32 /* StringLiteral */)) {
                            var b = getBaseTypeOfLiteralType(t);
                            if (typeIdenticalToSomeType(b, target.types)) {
                                (matchingTypes || (matchingTypes = [])).push(t, b);
                            }
                        }
                    }
                    // Next, to improve the quality of inferences, reduce the source and target types by
                    // removing the identically matched constituents. For example, when inferring from
                    // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'.
                    if (matchingTypes) {
                        source = removeTypesFromUnionOrIntersection(source, matchingTypes);
                        target = removeTypesFromUnionOrIntersection(target, matchingTypes);
                    }
                }
                if (target.flags & 540672 /* TypeVariable */) {
                    // If target is a type parameter, make an inference, unless the source type contains
                    // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
                    // Because the anyFunctionType is internal, it should not be exposed to the user by adding
                    // it as an inference candidate. Hopefully, a better candidate will come along that does
                    // not contain anyFunctionType when we come back to this argument for its second round
                    // of inference. Also, we exclude inferences for silentNeverType which is used as a wildcard
                    // when constructing types from type parameters that had no inference candidates.
                    if (source.flags & 8388608 /* ContainsAnyFunctionType */ || source === silentNeverType) {
                        return;
                    }
                    var inference = getInferenceInfoForType(target);
                    if (inference) {
                        if (!inference.isFixed) {
                            if (!inference.candidates || priority < inference.priority) {
                                inference.candidates = [source];
                                inference.priority = priority;
                            }
                            else if (priority === inference.priority) {
                                inference.candidates.push(source);
                            }
                            if (!(priority & 8 /* ReturnType */) && target.flags & 16384 /* TypeParameter */ && !isTypeParameterAtTopLevel(originalTarget, target)) {
                                inference.topLevel = false;
                            }
                        }
                        return;
                    }
                }
                else if (getObjectFlags(source) & 4 /* Reference */ && getObjectFlags(target) & 4 /* Reference */ && source.target === target.target) {
                    // If source and target are references to the same generic type, infer from type arguments
                    var sourceTypes = source.typeArguments || ts.emptyArray;
                    var targetTypes = target.typeArguments || ts.emptyArray;
                    var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
                    var variances = getVariances(source.target);
                    for (var i = 0; i < count; i++) {
                        if (i < variances.length && variances[i] === 2 /* Contravariant */) {
                            inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
                        }
                        else {
                            inferFromTypes(sourceTypes[i], targetTypes[i]);
                        }
                    }
                }
                else if (source.flags & 262144 /* Index */ && target.flags & 262144 /* Index */) {
                    inferFromTypes(source.type, target.type);
                }
                else if (source.flags & 524288 /* IndexedAccess */ && target.flags & 524288 /* IndexedAccess */) {
                    inferFromTypes(source.objectType, target.objectType);
                    inferFromTypes(source.indexType, target.indexType);
                }
                else if (target.flags & 196608 /* UnionOrIntersection */) {
                    var targetTypes = target.types;
                    var typeVariableCount = 0;
                    var typeVariable = void 0;
                    // First infer to each type in union or intersection that isn't a type variable
                    for (var _d = 0, targetTypes_3 = targetTypes; _d < targetTypes_3.length; _d++) {
                        var t = targetTypes_3[_d];
                        if (getInferenceInfoForType(t)) {
                            typeVariable = t;
                            typeVariableCount++;
                        }
                        else {
                            inferFromTypes(source, t);
                        }
                    }
                    // Next, if target containings a single naked type variable, make a secondary inference to that type
                    // variable. This gives meaningful results for union types in co-variant positions and intersection
                    // types in contra-variant positions (such as callback parameters).
                    if (typeVariableCount === 1) {
                        var savePriority = priority;
                        priority |= 2 /* NakedTypeVariable */;
                        inferFromTypes(source, typeVariable);
                        priority = savePriority;
                    }
                }
                else if (source.flags & 65536 /* Union */) {
                    // Source is a union or intersection type, infer from each constituent type
                    var sourceTypes = source.types;
                    for (var _e = 0, sourceTypes_3 = sourceTypes; _e < sourceTypes_3.length; _e++) {
                        var sourceType = sourceTypes_3[_e];
                        inferFromTypes(sourceType, target);
                    }
                }
                else {
                    source = getApparentType(source);
                    if (source.flags & (32768 /* Object */ | 131072 /* Intersection */)) {
                        var key = source.id + "," + target.id;
                        if (visited && visited.get(key)) {
                            return;
                        }
                        (visited || (visited = ts.createMap())).set(key, true);
                        // If we are already processing another target type with the same associated symbol (such as
                        // an instantiation of the same generic type), we do not explore this target as it would yield
                        // no further inferences. We exclude the static side of classes from this check since it shares
                        // its symbol with the instance side which would lead to false positives.
                        var isNonConstructorObject = target.flags & 32768 /* Object */ &&
                            !(getObjectFlags(target) & 16 /* Anonymous */ && target.symbol && target.symbol.flags & 32 /* Class */);
                        var symbol = isNonConstructorObject ? target.symbol : undefined;
                        if (symbol) {
                            if (ts.contains(symbolStack, symbol)) {
                                return;
                            }
                            (symbolStack || (symbolStack = [])).push(symbol);
                            inferFromObjectTypes(source, target);
                            symbolStack.pop();
                        }
                        else {
                            inferFromObjectTypes(source, target);
                        }
                    }
                }
            }
            function inferFromContravariantTypes(source, target) {
                if (strictFunctionTypes) {
                    priority ^= 1 /* Contravariant */;
                    inferFromTypes(source, target);
                    priority ^= 1 /* Contravariant */;
                }
                else {
                    inferFromTypes(source, target);
                }
            }
            function getInferenceInfoForType(type) {
                if (type.flags & 540672 /* TypeVariable */) {
                    for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
                        var inference = inferences_1[_i];
                        if (type === inference.typeParameter) {
                            return inference;
                        }
                    }
                }
                return undefined;
            }
            function inferFromObjectTypes(source, target) {
                if (isGenericMappedType(source) && isGenericMappedType(target)) {
                    // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
                    // from S to T and from X to Y.
                    inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
                    inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
                }
                if (getObjectFlags(target) & 32 /* Mapped */) {
                    var constraintType = getConstraintTypeFromMappedType(target);
                    if (constraintType.flags & 262144 /* Index */) {
                        // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X },
                        // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
                        // type and then make a secondary inference from that type to T. We make a secondary inference
                        // such that direct inferences to T get priority over inferences to Partial<T>, for example.
                        var inference = getInferenceInfoForType(constraintType.type);
                        if (inference && !inference.isFixed) {
                            var inferredType = inferTypeForHomomorphicMappedType(source, target);
                            if (inferredType) {
                                var savePriority = priority;
                                priority |= 4 /* MappedType */;
                                inferFromTypes(inferredType, inference.typeParameter);
                                priority = savePriority;
                            }
                        }
                        return;
                    }
                    if (constraintType.flags & 16384 /* TypeParameter */) {
                        // We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
                        // parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
                        inferFromTypes(getIndexType(source), constraintType);
                        inferFromTypes(getUnionType(ts.map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(target));
                        return;
                    }
                }
                // Infer from the members of source and target only if the two types are possibly related. We check
                // in both directions because we may be inferring for a co-variant or a contra-variant position.
                if (!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) || !getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false)) {
                    inferFromProperties(source, target);
                    inferFromSignatures(source, target, 0 /* Call */);
                    inferFromSignatures(source, target, 1 /* Construct */);
                    inferFromIndexTypes(source, target);
                }
            }
            function inferFromProperties(source, target) {
                var properties = getPropertiesOfObjectType(target);
                for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) {
                    var targetProp = properties_6[_i];
                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                    if (sourceProp) {
                        inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                    }
                }
            }
            function inferFromSignatures(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                var sourceLen = sourceSignatures.length;
                var targetLen = targetSignatures.length;
                var len = sourceLen < targetLen ? sourceLen : targetLen;
                for (var i = 0; i < len; i++) {
                    inferFromSignature(getErasedSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]));
                }
            }
            function inferFromSignature(source, target) {
                forEachMatchingParameterType(source, target, inferFromContravariantTypes);
                if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) {
                    inferFromTypes(source.typePredicate.type, target.typePredicate.type);
                }
                else {
                    inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
                }
            }
            function inferFromIndexTypes(source, target) {
                var targetStringIndexType = getIndexTypeOfType(target, 0 /* String */);
                if (targetStringIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 0 /* String */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetStringIndexType);
                    }
                }
                var targetNumberIndexType = getIndexTypeOfType(target, 1 /* Number */);
                if (targetNumberIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 1 /* Number */) ||
                        getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 1 /* Number */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetNumberIndexType);
                    }
                }
            }
        }
        function typeIdenticalToSomeType(type, types) {
            for (var _i = 0, types_12 = types; _i < types_12.length; _i++) {
                var t = types_12[_i];
                if (isTypeIdenticalTo(t, type)) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Return a new union or intersection type computed by removing a given set of types
         * from a given union or intersection type.
         */
        function removeTypesFromUnionOrIntersection(type, typesToRemove) {
            var reducedTypes = [];
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (!typeIdenticalToSomeType(t, typesToRemove)) {
                    reducedTypes.push(t);
                }
            }
            return type.flags & 65536 /* Union */ ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes);
        }
        function hasPrimitiveConstraint(type) {
            var constraint = getConstraintOfTypeParameter(type);
            return constraint && maybeTypeOfKind(constraint, 8190 /* Primitive */ | 262144 /* Index */);
        }
        function getInferredType(context, index) {
            var inference = context.inferences[index];
            var inferredType = inference.inferredType;
            if (!inferredType) {
                if (inference.candidates) {
                    // We widen inferred literal types if
                    // all inferences were made to top-level ocurrences of the type parameter, and
                    // the type parameter has no constraint or its constraint includes no primitive or literal types, and
                    // the type parameter was fixed during inference or does not occur at top-level in the return type.
                    var signature = context.signature;
                    var widenLiteralTypes = inference.topLevel &&
                        !hasPrimitiveConstraint(inference.typeParameter) &&
                        (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
                    var baseCandidates = widenLiteralTypes ? ts.sameMap(inference.candidates, getWidenedLiteralType) : inference.candidates;
                    // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
                    // union types were requested or if all inferences were made from the return type position, infer a
                    // union type. Otherwise, infer a common supertype.
                    var unwidenedType = inference.priority & 1 /* Contravariant */ ? getCommonSubtype(baseCandidates) :
                        context.flags & 1 /* InferUnionTypes */ || inference.priority & 8 /* ReturnType */ ? getUnionType(baseCandidates, /*subtypeReduction*/ true) :
                            getCommonSupertype(baseCandidates);
                    inferredType = getWidenedType(unwidenedType);
                }
                else if (context.flags & 2 /* NoDefault */) {
                    // We use silentNeverType as the wildcard that signals no inferences.
                    inferredType = silentNeverType;
                }
                else {
                    // Infer either the default or the empty object type when no inferences were
                    // made. It is important to remember that in this case, inference still
                    // succeeds, meaning there is no error for not having inference candidates. An
                    // inference error only occurs when there are *conflicting* candidates, i.e.
                    // candidates with no common supertype.
                    var defaultType = getDefaultFromTypeParameter(inference.typeParameter);
                    if (defaultType) {
                        // Instantiate the default type. Any forward reference to a type
                        // parameter should be instantiated to the empty object type.
                        inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context.signature.typeParameters, index), context));
                    }
                    else {
                        inferredType = getDefaultTypeArgumentType(!!(context.flags & 4 /* AnyDefault */));
                    }
                }
                inference.inferredType = inferredType;
                var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]);
                if (constraint) {
                    var instantiatedConstraint = instantiateType(constraint, context);
                    if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
                        inference.inferredType = inferredType = instantiatedConstraint;
                    }
                }
            }
            return inferredType;
        }
        function getDefaultTypeArgumentType(isInJavaScriptFile) {
            return isInJavaScriptFile ? anyType : emptyObjectType;
        }
        function getInferredTypes(context) {
            var result = [];
            for (var i = 0; i < context.inferences.length; i++) {
                result.push(getInferredType(context, i));
            }
            return result;
        }
        // EXPRESSION TYPE CHECKING
        function getResolvedSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                links.resolvedSymbol = !ts.nodeIsMissing(node) &&
                    resolveName(node, node.escapedText, 107455 /* Value */ | 1048576 /* ExportValue */, ts.Diagnostics.Cannot_find_name_0, node, !ts.isWriteOnlyAccess(node), ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol;
            }
            return links.resolvedSymbol;
        }
        function isInTypeQuery(node) {
            // TypeScript 1.0 spec (April 2014): 3.6.3
            // A type query consists of the keyword typeof followed by an expression.
            // The expression is restricted to a single identifier or a sequence of identifiers separated by periods
            return !!ts.findAncestor(node, function (n) { return n.kind === 162 /* TypeQuery */ ? true : n.kind === 71 /* Identifier */ || n.kind === 143 /* QualifiedName */ ? false : "quit"; });
        }
        // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers
        // separated by dots). The key consists of the id of the symbol referenced by the
        // leftmost identifier followed by zero or more property names separated by dots.
        // The result is undefined if the reference isn't a dotted name. We prefix nodes
        // occurring in an apparent type position with '@' because the control flow type
        // of such nodes may be based on the apparent type instead of the declared type.
        function getFlowCacheKey(node) {
            if (node.kind === 71 /* Identifier */) {
                var symbol = getResolvedSymbol(node);
                return symbol !== unknownSymbol ? (isApparentTypePosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
            }
            if (node.kind === 99 /* ThisKeyword */) {
                return "0";
            }
            if (node.kind === 179 /* PropertyAccessExpression */) {
                var key = getFlowCacheKey(node.expression);
                return key && key + "." + ts.idText(node.name);
            }
            if (node.kind === 176 /* BindingElement */) {
                var container = node.parent.parent;
                var key = container.kind === 176 /* BindingElement */ ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer));
                var text = getBindingElementNameText(node);
                var result = key && text && (key + "." + text);
                return result;
            }
            return undefined;
        }
        function getBindingElementNameText(element) {
            if (element.parent.kind === 174 /* ObjectBindingPattern */) {
                var name = element.propertyName || element.name;
                switch (name.kind) {
                    case 71 /* Identifier */:
                        return ts.idText(name);
                    case 144 /* ComputedPropertyName */:
                        return ts.isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined;
                    case 9 /* StringLiteral */:
                    case 8 /* NumericLiteral */:
                        return name.text;
                    default:
                        // Per types, array and object binding patterns remain, however they should never be present if propertyName is not defined
                        ts.Debug.fail("Unexpected name kind for binding element name");
                }
            }
            else {
                return "" + element.parent.elements.indexOf(element);
            }
        }
        function isMatchingReference(source, target) {
            switch (source.kind) {
                case 71 /* Identifier */:
                    return target.kind === 71 /* Identifier */ && getResolvedSymbol(source) === getResolvedSymbol(target) ||
                        (target.kind === 226 /* VariableDeclaration */ || target.kind === 176 /* BindingElement */) &&
                            getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source)) === getSymbolOfNode(target);
                case 99 /* ThisKeyword */:
                    return target.kind === 99 /* ThisKeyword */;
                case 97 /* SuperKeyword */:
                    return target.kind === 97 /* SuperKeyword */;
                case 179 /* PropertyAccessExpression */:
                    return target.kind === 179 /* PropertyAccessExpression */ &&
                        source.name.escapedText === target.name.escapedText &&
                        isMatchingReference(source.expression, target.expression);
                case 176 /* BindingElement */:
                    if (target.kind !== 179 /* PropertyAccessExpression */)
                        return false;
                    var t = target;
                    if (t.name.escapedText !== getBindingElementNameText(source))
                        return false;
                    if (source.parent.parent.kind === 176 /* BindingElement */ && isMatchingReference(source.parent.parent, t.expression)) {
                        return true;
                    }
                    if (source.parent.parent.kind === 226 /* VariableDeclaration */) {
                        var maybeId = source.parent.parent.initializer;
                        return maybeId && isMatchingReference(maybeId, t.expression);
                    }
            }
            return false;
        }
        function containsMatchingReference(source, target) {
            while (source.kind === 179 /* PropertyAccessExpression */) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        // Return true if target is a property access xxx.yyy, source is a property access xxx.zzz, the declared
        // type of xxx is a union type, and yyy is a property that is possibly a discriminant. We consider a property
        // a possible discriminant if its type differs in the constituents of containing union type, and if every
        // choice is a unit type or a union of unit types.
        function containsMatchingReferenceDiscriminant(source, target) {
            return target.kind === 179 /* PropertyAccessExpression */ &&
                containsMatchingReference(source, target.expression) &&
                isDiscriminantProperty(getDeclaredTypeOfReference(target.expression), target.name.escapedText);
        }
        function getDeclaredTypeOfReference(expr) {
            if (expr.kind === 71 /* Identifier */) {
                return getTypeOfSymbol(getResolvedSymbol(expr));
            }
            if (expr.kind === 179 /* PropertyAccessExpression */) {
                var type = getDeclaredTypeOfReference(expr.expression);
                return type && getTypeOfPropertyOfType(type, expr.name.escapedText);
            }
            return undefined;
        }
        function isDiscriminantProperty(type, name) {
            if (type && type.flags & 65536 /* Union */) {
                var prop = getUnionOrIntersectionProperty(type, name);
                if (prop && ts.getCheckFlags(prop) & 2 /* SyntheticProperty */) {
                    if (prop.isDiscriminantProperty === undefined) {
                        prop.isDiscriminantProperty = prop.checkFlags & 32 /* HasNonUniformType */ && isLiteralType(getTypeOfSymbol(prop));
                    }
                    return prop.isDiscriminantProperty;
                }
            }
            return false;
        }
        function findSingleDiscriminantProperty(sourceProperties, target) {
            var result;
            for (var _i = 0, sourceProperties_2 = sourceProperties; _i < sourceProperties_2.length; _i++) {
                var sourceProperty = sourceProperties_2[_i];
                if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
                    if (result) {
                        return undefined;
                    }
                    result = sourceProperty;
                }
            }
            return result;
        }
        function isOrContainsMatchingReference(source, target) {
            return isMatchingReference(source, target) || containsMatchingReference(source, target);
        }
        function hasMatchingArgument(callExpression, reference) {
            if (callExpression.arguments) {
                for (var _i = 0, _a = callExpression.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (isOrContainsMatchingReference(reference, argument)) {
                        return true;
                    }
                }
            }
            if (callExpression.expression.kind === 179 /* PropertyAccessExpression */ &&
                isOrContainsMatchingReference(reference, callExpression.expression.expression)) {
                return true;
            }
            return false;
        }
        function getFlowNodeId(flow) {
            if (!flow.id) {
                flow.id = nextFlowId;
                nextFlowId++;
            }
            return flow.id;
        }
        function typeMaybeAssignableTo(source, target) {
            if (!(source.flags & 65536 /* Union */)) {
                return isTypeAssignableTo(source, target);
            }
            for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (isTypeAssignableTo(t, target)) {
                    return true;
                }
            }
            return false;
        }
        // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
        // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
        // we remove type string.
        function getAssignmentReducedType(declaredType, assignedType) {
            if (declaredType !== assignedType) {
                if (assignedType.flags & 8192 /* Never */) {
                    return assignedType;
                }
                var reducedType = filterType(declaredType, function (t) { return typeMaybeAssignableTo(assignedType, t); });
                if (!(reducedType.flags & 8192 /* Never */)) {
                    return reducedType;
                }
            }
            return declaredType;
        }
        function getTypeFactsOfTypes(types) {
            var result = 0 /* None */;
            for (var _i = 0, types_13 = types; _i < types_13.length; _i++) {
                var t = types_13[_i];
                result |= getTypeFacts(t);
            }
            return result;
        }
        function isFunctionObjectType(type) {
            // We do a quick check for a "bind" property before performing the more expensive subtype
            // check. This gives us a quicker out in the common case where an object type is not a function.
            var resolved = resolveStructuredTypeMembers(type);
            return !!(resolved.callSignatures.length || resolved.constructSignatures.length ||
                resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType));
        }
        function getTypeFacts(type) {
            var flags = type.flags;
            if (flags & 2 /* String */) {
                return strictNullChecks ? 4079361 /* StringStrictFacts */ : 4194049 /* StringFacts */;
            }
            if (flags & 32 /* StringLiteral */) {
                var isEmpty = type.value === "";
                return strictNullChecks ?
                    isEmpty ? 3030785 /* EmptyStringStrictFacts */ : 1982209 /* NonEmptyStringStrictFacts */ :
                    isEmpty ? 3145473 /* EmptyStringFacts */ : 4194049 /* NonEmptyStringFacts */;
            }
            if (flags & (4 /* Number */ | 16 /* Enum */)) {
                return strictNullChecks ? 4079234 /* NumberStrictFacts */ : 4193922 /* NumberFacts */;
            }
            if (flags & 64 /* NumberLiteral */) {
                var isZero = type.value === 0;
                return strictNullChecks ?
                    isZero ? 3030658 /* ZeroStrictFacts */ : 1982082 /* NonZeroStrictFacts */ :
                    isZero ? 3145346 /* ZeroFacts */ : 4193922 /* NonZeroFacts */;
            }
            if (flags & 8 /* Boolean */) {
                return strictNullChecks ? 4078980 /* BooleanStrictFacts */ : 4193668 /* BooleanFacts */;
            }
            if (flags & 136 /* BooleanLike */) {
                return strictNullChecks ?
                    type === falseType ? 3030404 /* FalseStrictFacts */ : 1981828 /* TrueStrictFacts */ :
                    type === falseType ? 3145092 /* FalseFacts */ : 4193668 /* TrueFacts */;
            }
            if (flags & 32768 /* Object */) {
                return isFunctionObjectType(type) ?
                    strictNullChecks ? 6164448 /* FunctionStrictFacts */ : 8376288 /* FunctionFacts */ :
                    strictNullChecks ? 6166480 /* ObjectStrictFacts */ : 8378320 /* ObjectFacts */;
            }
            if (flags & (1024 /* Void */ | 2048 /* Undefined */)) {
                return 2457472 /* UndefinedFacts */;
            }
            if (flags & 4096 /* Null */) {
                return 2340752 /* NullFacts */;
            }
            if (flags & 512 /* ESSymbol */) {
                return strictNullChecks ? 1981320 /* SymbolStrictFacts */ : 4193160 /* SymbolFacts */;
            }
            if (flags & 16777216 /* NonPrimitive */) {
                return strictNullChecks ? 6166480 /* ObjectStrictFacts */ : 8378320 /* ObjectFacts */;
            }
            if (flags & 540672 /* TypeVariable */) {
                return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType);
            }
            if (flags & 196608 /* UnionOrIntersection */) {
                return getTypeFactsOfTypes(type.types);
            }
            return 8388607 /* All */;
        }
        function getTypeWithFacts(type, include) {
            if (type.flags & 524288 /* IndexedAccess */) {
                // TODO (weswig): This is a substitute for a lazy negated type to remove the types indicated by the TypeFacts from the (potential) union the IndexedAccess refers to
                //  - See discussion in https://github.com/Microsoft/TypeScript/pull/19275 for details, and test `strictNullNotNullIndexTypeShouldWork` for current behavior
                var baseConstraint = getBaseConstraintOfType(type) || emptyObjectType;
                var result = filterType(baseConstraint, function (t) { return (getTypeFacts(t) & include) !== 0; });
                if (result !== baseConstraint) {
                    return result;
                }
                return type;
            }
            return filterType(type, function (t) { return (getTypeFacts(t) & include) !== 0; });
        }
        function getTypeWithDefault(type, defaultExpression) {
            if (defaultExpression) {
                var defaultType = getTypeOfExpression(defaultExpression);
                return getUnionType([getTypeWithFacts(type, 131072 /* NEUndefined */), defaultType]);
            }
            return type;
        }
        function getTypeOfDestructuredProperty(type, name) {
            var text = ts.getTextOfPropertyName(name);
            return getTypeOfPropertyOfType(type, text) ||
                isNumericLiteralName(text) && getIndexTypeOfType(type, 1 /* Number */) ||
                getIndexTypeOfType(type, 0 /* String */) ||
                unknownType;
        }
        function getTypeOfDestructuredArrayElement(type, index) {
            return isTupleLikeType(type) && getTypeOfPropertyOfType(type, "" + index) ||
                checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) ||
                unknownType;
        }
        function getTypeOfDestructuredSpreadExpression(type) {
            return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType);
        }
        function getAssignedTypeOfBinaryExpression(node) {
            var isDestructuringDefaultAssignment = node.parent.kind === 177 /* ArrayLiteralExpression */ && isDestructuringAssignmentTarget(node.parent) ||
                node.parent.kind === 261 /* PropertyAssignment */ && isDestructuringAssignmentTarget(node.parent.parent);
            return isDestructuringDefaultAssignment ?
                getTypeWithDefault(getAssignedType(node), node.right) :
                getTypeOfExpression(node.right);
        }
        function isDestructuringAssignmentTarget(parent) {
            return parent.parent.kind === 194 /* BinaryExpression */ && parent.parent.left === parent ||
                parent.parent.kind === 216 /* ForOfStatement */ && parent.parent.initializer === parent;
        }
        function getAssignedTypeOfArrayLiteralElement(node, element) {
            return getTypeOfDestructuredArrayElement(getAssignedType(node), ts.indexOf(node.elements, element));
        }
        function getAssignedTypeOfSpreadExpression(node) {
            return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent));
        }
        function getAssignedTypeOfPropertyAssignment(node) {
            return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name);
        }
        function getAssignedTypeOfShorthandPropertyAssignment(node) {
            return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer);
        }
        function getAssignedType(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 215 /* ForInStatement */:
                    return stringType;
                case 216 /* ForOfStatement */:
                    return checkRightHandSideOfForOf(parent.expression, parent.awaitModifier) || unknownType;
                case 194 /* BinaryExpression */:
                    return getAssignedTypeOfBinaryExpression(parent);
                case 188 /* DeleteExpression */:
                    return undefinedType;
                case 177 /* ArrayLiteralExpression */:
                    return getAssignedTypeOfArrayLiteralElement(parent, node);
                case 198 /* SpreadElement */:
                    return getAssignedTypeOfSpreadExpression(parent);
                case 261 /* PropertyAssignment */:
                    return getAssignedTypeOfPropertyAssignment(parent);
                case 262 /* ShorthandPropertyAssignment */:
                    return getAssignedTypeOfShorthandPropertyAssignment(parent);
            }
            return unknownType;
        }
        function getInitialTypeOfBindingElement(node) {
            var pattern = node.parent;
            var parentType = getInitialType(pattern.parent);
            var type = pattern.kind === 174 /* ObjectBindingPattern */ ?
                getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) :
                !node.dotDotDotToken ?
                    getTypeOfDestructuredArrayElement(parentType, ts.indexOf(pattern.elements, node)) :
                    getTypeOfDestructuredSpreadExpression(parentType);
            return getTypeWithDefault(type, node.initializer);
        }
        function getTypeOfInitializer(node) {
            // Return the cached type if one is available. If the type of the variable was inferred
            // from its initializer, we'll already have cached the type. Otherwise we compute it now
            // without caching such that transient types are reflected.
            var links = getNodeLinks(node);
            return links.resolvedType || getTypeOfExpression(node);
        }
        function getInitialTypeOfVariableDeclaration(node) {
            if (node.initializer) {
                return getTypeOfInitializer(node.initializer);
            }
            if (node.parent.parent.kind === 215 /* ForInStatement */) {
                return stringType;
            }
            if (node.parent.parent.kind === 216 /* ForOfStatement */) {
                return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || unknownType;
            }
            return unknownType;
        }
        function getInitialType(node) {
            return node.kind === 226 /* VariableDeclaration */ ?
                getInitialTypeOfVariableDeclaration(node) :
                getInitialTypeOfBindingElement(node);
        }
        function getInitialOrAssignedType(node) {
            return node.kind === 226 /* VariableDeclaration */ || node.kind === 176 /* BindingElement */ ?
                getInitialType(node) :
                getAssignedType(node);
        }
        function isEmptyArrayAssignment(node) {
            return node.kind === 226 /* VariableDeclaration */ && node.initializer &&
                isEmptyArrayLiteral(node.initializer) ||
                node.kind !== 176 /* BindingElement */ && node.parent.kind === 194 /* BinaryExpression */ &&
                    isEmptyArrayLiteral(node.parent.right);
        }
        function getReferenceCandidate(node) {
            switch (node.kind) {
                case 185 /* ParenthesizedExpression */:
                    return getReferenceCandidate(node.expression);
                case 194 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 58 /* EqualsToken */:
                            return getReferenceCandidate(node.left);
                        case 26 /* CommaToken */:
                            return getReferenceCandidate(node.right);
                    }
            }
            return node;
        }
        function getReferenceRoot(node) {
            var parent = node.parent;
            return parent.kind === 185 /* ParenthesizedExpression */ ||
                parent.kind === 194 /* BinaryExpression */ && parent.operatorToken.kind === 58 /* EqualsToken */ && parent.left === node ||
                parent.kind === 194 /* BinaryExpression */ && parent.operatorToken.kind === 26 /* CommaToken */ && parent.right === node ?
                getReferenceRoot(parent) : node;
        }
        function getTypeOfSwitchClause(clause) {
            if (clause.kind === 257 /* CaseClause */) {
                var caseType = getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
                return isUnitType(caseType) ? caseType : undefined;
            }
            return neverType;
        }
        function getSwitchClauseTypes(switchStatement) {
            var links = getNodeLinks(switchStatement);
            if (!links.switchTypes) {
                // If all case clauses specify expressions that have unit types, we return an array
                // of those unit types. Otherwise we return an empty array.
                links.switchTypes = [];
                for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                    var clause = _a[_i];
                    var type = getTypeOfSwitchClause(clause);
                    if (type === undefined) {
                        return links.switchTypes = ts.emptyArray;
                    }
                    links.switchTypes.push(type);
                }
            }
            return links.switchTypes;
        }
        function eachTypeContainedIn(source, types) {
            return source.flags & 65536 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source);
        }
        function isTypeSubsetOf(source, target) {
            return source === target || target.flags & 65536 /* Union */ && isTypeSubsetOfUnion(source, target);
        }
        function isTypeSubsetOfUnion(source, target) {
            if (source.flags & 65536 /* Union */) {
                for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (!containsType(target.types, t)) {
                        return false;
                    }
                }
                return true;
            }
            if (source.flags & 256 /* EnumLiteral */ && getBaseTypeOfEnumLiteralType(source) === target) {
                return true;
            }
            return containsType(target.types, source);
        }
        function forEachType(type, f) {
            return type.flags & 65536 /* Union */ ? ts.forEach(type.types, f) : f(type);
        }
        function filterType(type, f) {
            if (type.flags & 65536 /* Union */) {
                var types = type.types;
                var filtered = ts.filter(types, f);
                return filtered === types ? type : getUnionTypeFromSortedList(filtered);
            }
            return f(type) ? type : neverType;
        }
        // Apply a mapping function to a type and return the resulting type. If the source type
        // is a union type, the mapping function is applied to each constituent type and a union
        // of the resulting types is returned.
        function mapType(type, mapper) {
            if (!(type.flags & 65536 /* Union */)) {
                return mapper(type);
            }
            var types = type.types;
            var mappedType;
            var mappedTypes;
            for (var _i = 0, types_14 = types; _i < types_14.length; _i++) {
                var current = types_14[_i];
                var t = mapper(current);
                if (t) {
                    if (!mappedType) {
                        mappedType = t;
                    }
                    else if (!mappedTypes) {
                        mappedTypes = [mappedType, t];
                    }
                    else {
                        mappedTypes.push(t);
                    }
                }
            }
            return mappedTypes ? getUnionType(mappedTypes) : mappedType;
        }
        function extractTypesOfKind(type, kind) {
            return filterType(type, function (t) { return (t.flags & kind) !== 0; });
        }
        // Return a new type in which occurrences of the string and number primitive types in
        // typeWithPrimitives have been replaced with occurrences of string literals and numeric
        // literals in typeWithLiterals, respectively.
        function replacePrimitivesWithLiterals(typeWithPrimitives, typeWithLiterals) {
            if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 32 /* StringLiteral */) ||
                isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 64 /* NumberLiteral */)) {
                return mapType(typeWithPrimitives, function (t) {
                    return t.flags & 2 /* String */ ? extractTypesOfKind(typeWithLiterals, 2 /* String */ | 32 /* StringLiteral */) :
                        t.flags & 4 /* Number */ ? extractTypesOfKind(typeWithLiterals, 4 /* Number */ | 64 /* NumberLiteral */) :
                            t;
                });
            }
            return typeWithPrimitives;
        }
        function isIncomplete(flowType) {
            return flowType.flags === 0;
        }
        function getTypeFromFlowType(flowType) {
            return flowType.flags === 0 ? flowType.type : flowType;
        }
        function createFlowType(type, incomplete) {
            return incomplete ? { flags: 0, type: type } : type;
        }
        // An evolving array type tracks the element types that have so far been seen in an
        // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
        // array types are ultimately converted into manifest array types (using getFinalArrayType)
        // and never escape the getFlowTypeOfReference function.
        function createEvolvingArrayType(elementType) {
            var result = createObjectType(256 /* EvolvingArray */);
            result.elementType = elementType;
            return result;
        }
        function getEvolvingArrayType(elementType) {
            return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType));
        }
        // When adding evolving array element types we do not perform subtype reduction. Instead,
        // we defer subtype reduction until the evolving array type is finalized into a manifest
        // array type.
        function addEvolvingArrayElementType(evolvingArrayType, node) {
            var elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node));
            return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
        }
        function createFinalArrayType(elementType) {
            return elementType.flags & 8192 /* Never */ ?
                autoArrayType :
                createArrayType(elementType.flags & 65536 /* Union */ ?
                    getUnionType(elementType.types, /*subtypeReduction*/ true) :
                    elementType);
        }
        // We perform subtype reduction upon obtaining the final array type from an evolving array type.
        function getFinalArrayType(evolvingArrayType) {
            return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType));
        }
        function finalizeEvolvingArrayType(type) {
            return getObjectFlags(type) & 256 /* EvolvingArray */ ? getFinalArrayType(type) : type;
        }
        function getElementTypeOfEvolvingArrayType(type) {
            return getObjectFlags(type) & 256 /* EvolvingArray */ ? type.elementType : neverType;
        }
        function isEvolvingArrayTypeList(types) {
            var hasEvolvingArrayType = false;
            for (var _i = 0, types_15 = types; _i < types_15.length; _i++) {
                var t = types_15[_i];
                if (!(t.flags & 8192 /* Never */)) {
                    if (!(getObjectFlags(t) & 256 /* EvolvingArray */)) {
                        return false;
                    }
                    hasEvolvingArrayType = true;
                }
            }
            return hasEvolvingArrayType;
        }
        // At flow control branch or loop junctions, if the type along every antecedent code path
        // is an evolving array type, we construct a combined evolving array type. Otherwise we
        // finalize all evolving array types.
        function getUnionOrEvolvingArrayType(types, subtypeReduction) {
            return isEvolvingArrayTypeList(types) ?
                getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))) :
                getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
        }
        // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or
        // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type.
        function isEvolvingArrayOperationTarget(node) {
            var root = getReferenceRoot(node);
            var parent = root.parent;
            var isLengthPushOrUnshift = parent.kind === 179 /* PropertyAccessExpression */ && (parent.name.escapedText === "length" ||
                parent.parent.kind === 181 /* CallExpression */ && ts.isPushOrUnshiftIdentifier(parent.name));
            var isElementAssignment = parent.kind === 180 /* ElementAccessExpression */ &&
                parent.expression === root &&
                parent.parent.kind === 194 /* BinaryExpression */ &&
                parent.parent.operatorToken.kind === 58 /* EqualsToken */ &&
                parent.parent.left === parent &&
                !ts.isAssignmentTarget(parent.parent) &&
                isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */);
            return isLengthPushOrUnshift || isElementAssignment;
        }
        function maybeTypePredicateCall(node) {
            var links = getNodeLinks(node);
            if (links.maybeTypePredicate === undefined) {
                links.maybeTypePredicate = getMaybeTypePredicate(node);
            }
            return links.maybeTypePredicate;
        }
        function getMaybeTypePredicate(node) {
            if (node.expression.kind !== 97 /* SuperKeyword */) {
                var funcType = checkNonNullExpression(node.expression);
                if (funcType !== silentNeverType) {
                    var apparentType = getApparentType(funcType);
                    if (apparentType !== unknownType) {
                        var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
                        return !!ts.forEach(callSignatures, function (sig) { return sig.typePredicate; });
                    }
                }
            }
            return false;
        }
        function reportFlowControlError(node) {
            var block = ts.findAncestor(node, ts.isFunctionOrModuleBlock);
            var sourceFile = ts.getSourceFileOfNode(node);
            var span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
            diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
        }
        function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, couldBeUninitialized) {
            if (initialType === void 0) { initialType = declaredType; }
            var key;
            var flowDepth = 0;
            if (flowAnalysisDisabled) {
                return unknownType;
            }
            if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & 17810175 /* Narrowable */)) {
                return declaredType;
            }
            var sharedFlowStart = sharedFlowCount;
            var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
            sharedFlowCount = sharedFlowStart;
            // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
            // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
            // on empty arrays are possible without implicit any errors and new element types can be inferred without
            // type mismatch errors.
            var resultType = getObjectFlags(evolvedType) & 256 /* EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType);
            if (reference.parent.kind === 203 /* NonNullExpression */ && getTypeWithFacts(resultType, 524288 /* NEUndefinedOrNull */).flags & 8192 /* Never */) {
                return declaredType;
            }
            return resultType;
            function getTypeAtFlowNode(flow) {
                if (flowDepth === 2500) {
                    // We have made 2500 recursive invocations. To avoid overflowing the call stack we report an error
                    // and disable further control flow analysis in the containing function or module body.
                    flowAnalysisDisabled = true;
                    reportFlowControlError(reference);
                    return unknownType;
                }
                flowDepth++;
                while (true) {
                    var flags = flow.flags;
                    if (flags & 1024 /* Shared */) {
                        // We cache results of flow type resolution for shared nodes that were previously visited in
                        // the same getFlowTypeOfReference invocation. A node is considered shared when it is the
                        // antecedent of more than one node.
                        for (var i = sharedFlowStart; i < sharedFlowCount; i++) {
                            if (sharedFlowNodes[i] === flow) {
                                flowDepth--;
                                return sharedFlowTypes[i];
                            }
                        }
                    }
                    var type = void 0;
                    if (flags & 4096 /* AfterFinally */) {
                        // block flow edge: finally -> pre-try (for larger explanation check comment in binder.ts - bindTryStatement
                        flow.locked = true;
                        type = getTypeAtFlowNode(flow.antecedent);
                        flow.locked = false;
                    }
                    else if (flags & 2048 /* PreFinally */) {
                        // locked pre-finally flows are filtered out in getTypeAtFlowBranchLabel
                        // so here just redirect to antecedent
                        flow = flow.antecedent;
                        continue;
                    }
                    else if (flags & 16 /* Assignment */) {
                        type = getTypeAtFlowAssignment(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 96 /* Condition */) {
                        type = getTypeAtFlowCondition(flow);
                    }
                    else if (flags & 128 /* SwitchClause */) {
                        type = getTypeAtSwitchClause(flow);
                    }
                    else if (flags & 12 /* Label */) {
                        if (flow.antecedents.length === 1) {
                            flow = flow.antecedents[0];
                            continue;
                        }
                        type = flags & 4 /* BranchLabel */ ?
                            getTypeAtFlowBranchLabel(flow) :
                            getTypeAtFlowLoopLabel(flow);
                    }
                    else if (flags & 256 /* ArrayMutation */) {
                        type = getTypeAtFlowArrayMutation(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 2 /* Start */) {
                        // Check if we should continue with the control flow of the containing function.
                        var container = flow.container;
                        if (container && container !== flowContainer && reference.kind !== 179 /* PropertyAccessExpression */ && reference.kind !== 99 /* ThisKeyword */) {
                            flow = container.flowNode;
                            continue;
                        }
                        // At the top of the flow we have the initial type.
                        type = initialType;
                    }
                    else {
                        // Unreachable code errors are reported in the binding phase. Here we
                        // simply return the non-auto declared type to reduce follow-on errors.
                        type = convertAutoToAny(declaredType);
                    }
                    if (flags & 1024 /* Shared */) {
                        // Record visited node and the associated type in the cache.
                        sharedFlowNodes[sharedFlowCount] = flow;
                        sharedFlowTypes[sharedFlowCount] = type;
                        sharedFlowCount++;
                    }
                    flowDepth--;
                    return type;
                }
            }
            function getTypeAtFlowAssignment(flow) {
                var node = flow.node;
                // Assignments only narrow the computed type if the declared type is a union type. Thus, we
                // only need to evaluate the assigned type if the declared type is a union type.
                if (isMatchingReference(reference, node)) {
                    if (ts.getAssignmentTargetKind(node) === 2 /* Compound */) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
                    }
                    if (declaredType === autoType || declaredType === autoArrayType) {
                        if (isEmptyArrayAssignment(node)) {
                            return getEvolvingArrayType(neverType);
                        }
                        var assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node));
                        return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType;
                    }
                    if (declaredType.flags & 65536 /* Union */) {
                        return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node));
                    }
                    return declaredType;
                }
                // We didn't have a direct match. However, if the reference is a dotted name, this
                // may be an assignment to a left hand part of the reference. For example, for a
                // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
                // return the declared type.
                if (containsMatchingReference(reference, node)) {
                    return declaredType;
                }
                // Assignment doesn't affect reference
                return undefined;
            }
            function getTypeAtFlowArrayMutation(flow) {
                if (declaredType === autoType || declaredType === autoArrayType) {
                    var node = flow.node;
                    var expr = node.kind === 181 /* CallExpression */ ?
                        node.expression.expression :
                        node.left.expression;
                    if (isMatchingReference(reference, getReferenceCandidate(expr))) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        var type = getTypeFromFlowType(flowType);
                        if (getObjectFlags(type) & 256 /* EvolvingArray */) {
                            var evolvedType_1 = type;
                            if (node.kind === 181 /* CallExpression */) {
                                for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                                    var arg = _a[_i];
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, arg);
                                }
                            }
                            else {
                                var indexType = getTypeOfExpression(node.left.argumentExpression);
                                if (isTypeAssignableToKind(indexType, 84 /* NumberLike */)) {
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right);
                                }
                            }
                            return evolvedType_1 === type ? flowType : createFlowType(evolvedType_1, isIncomplete(flowType));
                        }
                        return flowType;
                    }
                }
                return undefined;
            }
            function getTypeAtFlowCondition(flow) {
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (type.flags & 8192 /* Never */) {
                    return flowType;
                }
                // If we have an antecedent type (meaning we're reachable in some way), we first
                // attempt to narrow the antecedent type. If that produces the never type, and if
                // the antecedent type is incomplete (i.e. a transient type in a loop), then we
                // take the type guard as an indication that control *could* reach here once we
                // have the complete type. We proceed by switching to the silent never type which
                // doesn't report errors when operators are applied to it. Note that this is the
                // *only* place a silent never type is ever generated.
                var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0;
                var nonEvolvingType = finalizeEvolvingArrayType(type);
                var narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue);
                if (narrowedType === nonEvolvingType) {
                    return flowType;
                }
                var incomplete = isIncomplete(flowType);
                var resultType = incomplete && narrowedType.flags & 8192 /* Never */ ? silentNeverType : narrowedType;
                return createFlowType(resultType, incomplete);
            }
            function getTypeAtSwitchClause(flow) {
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                var expr = flow.switchStatement.expression;
                if (isMatchingReference(reference, expr)) {
                    type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else if (isMatchingReferenceDiscriminant(expr, type)) {
                    type = narrowTypeByDiscriminant(type, expr, function (t) { return narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd); });
                }
                return createFlowType(type, isIncomplete(flowType));
            }
            function getTypeAtFlowBranchLabel(flow) {
                var antecedentTypes = [];
                var subtypeReduction = false;
                var seenIncomplete = false;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    if (antecedent.flags & 2048 /* PreFinally */ && antecedent.lock.locked) {
                        // if flow correspond to branch from pre-try to finally and this branch is locked - this means that
                        // we initially have started following the flow outside the finally block.
                        // in this case we should ignore this branch.
                        continue;
                    }
                    var flowType = getTypeAtFlowNode(antecedent);
                    var type = getTypeFromFlowType(flowType);
                    // If the type at a particular antecedent path is the declared type and the
                    // reference is known to always be assigned (i.e. when declared and initial types
                    // are the same), there is no reason to process more antecedents since the only
                    // possible outcome is subtypes that will be removed in the final union type anyway.
                    if (type === declaredType && declaredType === initialType) {
                        return type;
                    }
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    if (isIncomplete(flowType)) {
                        seenIncomplete = true;
                    }
                }
                return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction), seenIncomplete);
            }
            function getTypeAtFlowLoopLabel(flow) {
                // If we have previously computed the control flow type for the reference at
                // this flow loop junction, return the cached type.
                var id = getFlowNodeId(flow);
                var cache = flowLoopCaches[id] || (flowLoopCaches[id] = ts.createMap());
                if (!key) {
                    key = getFlowCacheKey(reference);
                    // No cache key is generated when binding patterns are in unnarrowable situations
                    if (!key) {
                        return declaredType;
                    }
                }
                var cached = cache.get(key);
                if (cached) {
                    return cached;
                }
                // If this flow loop junction and reference are already being processed, return
                // the union of the types computed for each branch so far, marked as incomplete.
                // It is possible to see an empty array in cases where loops are nested and the
                // back edge of the outer loop reaches an inner loop that is already being analyzed.
                // In such cases we restart the analysis of the inner loop, which will then see
                // a non-empty in-process array for the outer loop and eventually terminate because
                // the first antecedent of a loop junction is always the non-looping control flow
                // path that leads to the top.
                for (var i = flowLoopStart; i < flowLoopCount; i++) {
                    if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
                        return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true);
                    }
                }
                // Add the flow loop junction and reference to the in-process stack and analyze
                // each antecedent code path.
                var antecedentTypes = [];
                var subtypeReduction = false;
                var firstAntecedentType;
                flowLoopNodes[flowLoopCount] = flow;
                flowLoopKeys[flowLoopCount] = key;
                flowLoopTypes[flowLoopCount] = antecedentTypes;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    flowLoopCount++;
                    var flowType = getTypeAtFlowNode(antecedent);
                    flowLoopCount--;
                    if (!firstAntecedentType) {
                        firstAntecedentType = flowType;
                    }
                    var type = getTypeFromFlowType(flowType);
                    // If we see a value appear in the cache it is a sign that control flow  analysis
                    // was restarted and completed by checkExpressionCached. We can simply pick up
                    // the resulting type and bail out.
                    var cached_1 = cache.get(key);
                    if (cached_1) {
                        return cached_1;
                    }
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    // If the type at a particular antecedent path is the declared type there is no
                    // reason to process more antecedents since the only possible outcome is subtypes
                    // that will be removed in the final union type anyway.
                    if (type === declaredType) {
                        break;
                    }
                }
                // The result is incomplete if the first antecedent (the non-looping control flow path)
                // is incomplete.
                var result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction);
                if (isIncomplete(firstAntecedentType)) {
                    return createFlowType(result, /*incomplete*/ true);
                }
                cache.set(key, result);
                return result;
            }
            function isMatchingReferenceDiscriminant(expr, computedType) {
                return expr.kind === 179 /* PropertyAccessExpression */ &&
                    computedType.flags & 65536 /* Union */ &&
                    isMatchingReference(reference, expr.expression) &&
                    isDiscriminantProperty(computedType, expr.name.escapedText);
            }
            function narrowTypeByDiscriminant(type, propAccess, narrowType) {
                var propName = propAccess.name.escapedText;
                var propType = getTypeOfPropertyOfType(type, propName);
                var narrowedPropType = propType && narrowType(propType);
                return propType === narrowedPropType ? type : filterType(type, function (t) { return isTypeComparableTo(getTypeOfPropertyOfType(t, propName), narrowedPropType); });
            }
            function narrowTypeByTruthiness(type, expr, assumeTrue) {
                if (isMatchingReference(reference, expr)) {
                    return getTypeWithFacts(type, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */);
                }
                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */); });
                }
                if (containsMatchingReferenceDiscriminant(reference, expr)) {
                    return declaredType;
                }
                return type;
            }
            function narrowTypeByBinaryExpression(type, expr, assumeTrue) {
                switch (expr.operatorToken.kind) {
                    case 58 /* EqualsToken */:
                        return narrowTypeByTruthiness(type, expr.left, assumeTrue);
                    case 32 /* EqualsEqualsToken */:
                    case 33 /* ExclamationEqualsToken */:
                    case 34 /* EqualsEqualsEqualsToken */:
                    case 35 /* ExclamationEqualsEqualsToken */:
                        var operator_1 = expr.operatorToken.kind;
                        var left_1 = getReferenceCandidate(expr.left);
                        var right_1 = getReferenceCandidate(expr.right);
                        if (left_1.kind === 189 /* TypeOfExpression */ && right_1.kind === 9 /* StringLiteral */) {
                            return narrowTypeByTypeof(type, left_1, operator_1, right_1, assumeTrue);
                        }
                        if (right_1.kind === 189 /* TypeOfExpression */ && left_1.kind === 9 /* StringLiteral */) {
                            return narrowTypeByTypeof(type, right_1, operator_1, left_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, left_1)) {
                            return narrowTypeByEquality(type, operator_1, right_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, right_1)) {
                            return narrowTypeByEquality(type, operator_1, left_1, assumeTrue);
                        }
                        if (isMatchingReferenceDiscriminant(left_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, left_1, function (t) { return narrowTypeByEquality(t, operator_1, right_1, assumeTrue); });
                        }
                        if (isMatchingReferenceDiscriminant(right_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, right_1, function (t) { return narrowTypeByEquality(t, operator_1, left_1, assumeTrue); });
                        }
                        if (containsMatchingReferenceDiscriminant(reference, left_1) || containsMatchingReferenceDiscriminant(reference, right_1)) {
                            return declaredType;
                        }
                        break;
                    case 93 /* InstanceOfKeyword */:
                        return narrowTypeByInstanceof(type, expr, assumeTrue);
                    case 26 /* CommaToken */:
                        return narrowType(type, expr.right, assumeTrue);
                }
                return type;
            }
            function narrowTypeByEquality(type, operator, value, assumeTrue) {
                if (type.flags & 1 /* Any */) {
                    return type;
                }
                if (operator === 33 /* ExclamationEqualsToken */ || operator === 35 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                var valueType = getTypeOfExpression(value);
                if (valueType.flags & 6144 /* Nullable */) {
                    if (!strictNullChecks) {
                        return type;
                    }
                    var doubleEquals = operator === 32 /* EqualsEqualsToken */ || operator === 33 /* ExclamationEqualsToken */;
                    var facts = doubleEquals ?
                        assumeTrue ? 65536 /* EQUndefinedOrNull */ : 524288 /* NEUndefinedOrNull */ :
                        value.kind === 95 /* NullKeyword */ ?
                            assumeTrue ? 32768 /* EQNull */ : 262144 /* NENull */ :
                            assumeTrue ? 16384 /* EQUndefined */ : 131072 /* NEUndefined */;
                    return getTypeWithFacts(type, facts);
                }
                if (type.flags & 16810497 /* NotUnionOrUnit */) {
                    return type;
                }
                if (assumeTrue) {
                    var narrowedType = filterType(type, function (t) { return areTypesComparable(t, valueType); });
                    return narrowedType.flags & 8192 /* Never */ ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
                }
                if (isUnitType(valueType)) {
                    var regularType_1 = getRegularTypeOfLiteralType(valueType);
                    return filterType(type, function (t) { return getRegularTypeOfLiteralType(t) !== regularType_1; });
                }
                return type;
            }
            function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) {
                // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands
                var target = getReferenceCandidate(typeOfExpr.expression);
                if (!isMatchingReference(reference, target)) {
                    // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
                    // narrowed type of 'y' to its declared type.
                    if (containsMatchingReference(reference, target)) {
                        return declaredType;
                    }
                    return type;
                }
                if (operator === 33 /* ExclamationEqualsToken */ || operator === 35 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                if (assumeTrue && !(type.flags & 65536 /* Union */)) {
                    // We narrow a non-union type to an exact primitive type if the non-union type
                    // is a supertype of that primitive type. For example, type 'any' can be narrowed
                    // to one of the primitive types.
                    var targetType = typeofTypesByName.get(literal.text);
                    if (targetType) {
                        if (isTypeSubtypeOf(targetType, type)) {
                            return targetType;
                        }
                        if (type.flags & 540672 /* TypeVariable */) {
                            var constraint = getBaseConstraintOfType(type) || anyType;
                            if (isTypeSubtypeOf(targetType, constraint)) {
                                return getIntersectionType([type, targetType]);
                            }
                        }
                    }
                }
                var facts = assumeTrue ?
                    typeofEQFacts.get(literal.text) || 64 /* TypeofEQHostObject */ :
                    typeofNEFacts.get(literal.text) || 8192 /* TypeofNEHostObject */;
                return getTypeWithFacts(type, facts);
            }
            function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) {
                // We only narrow if all case expressions specify values with unit types
                var switchTypes = getSwitchClauseTypes(switchStatement);
                if (!switchTypes.length) {
                    return type;
                }
                var clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
                var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType);
                var discriminantType = getUnionType(clauseTypes);
                var caseType = discriminantType.flags & 8192 /* Never */ ? neverType :
                    replacePrimitivesWithLiterals(filterType(type, function (t) { return isTypeComparableTo(discriminantType, t); }), discriminantType);
                if (!hasDefaultClause) {
                    return caseType;
                }
                var defaultType = filterType(type, function (t) { return !(isUnitType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(t))); });
                return caseType.flags & 8192 /* Never */ ? defaultType : getUnionType([caseType, defaultType]);
            }
            function narrowTypeByInstanceof(type, expr, assumeTrue) {
                var left = getReferenceCandidate(expr.left);
                if (!isMatchingReference(reference, left)) {
                    // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the
                    // narrowed type of 'y' to its declared type.
                    if (containsMatchingReference(reference, left)) {
                        return declaredType;
                    }
                    return type;
                }
                // Check that right operand is a function type with a prototype property
                var rightType = getTypeOfExpression(expr.right);
                if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
                    return type;
                }
                var targetType;
                var prototypeProperty = getPropertyOfType(rightType, "prototype");
                if (prototypeProperty) {
                    // Target type is type of the prototype property
                    var prototypePropertyType = getTypeOfSymbol(prototypeProperty);
                    if (!isTypeAny(prototypePropertyType)) {
                        targetType = prototypePropertyType;
                    }
                }
                // Don't narrow from 'any' if the target type is exactly 'Object' or 'Function'
                if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) {
                    return type;
                }
                if (!targetType) {
                    // Target type is type of construct signature
                    var constructSignatures = void 0;
                    if (getObjectFlags(rightType) & 2 /* Interface */) {
                        constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
                    }
                    else if (getObjectFlags(rightType) & 16 /* Anonymous */) {
                        constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
                    }
                    if (constructSignatures && constructSignatures.length) {
                        targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); }));
                    }
                }
                if (targetType) {
                    return getNarrowedType(type, targetType, assumeTrue, isTypeInstanceOf);
                }
                return type;
            }
            function getNarrowedType(type, candidate, assumeTrue, isRelated) {
                if (!assumeTrue) {
                    return filterType(type, function (t) { return !isRelated(t, candidate); });
                }
                // If the current type is a union type, remove all constituents that couldn't be instances of
                // the candidate type. If one or more constituents remain, return a union of those.
                if (type.flags & 65536 /* Union */) {
                    var assignableType = filterType(type, function (t) { return isRelated(t, candidate); });
                    if (!(assignableType.flags & 8192 /* Never */)) {
                        return assignableType;
                    }
                }
                // If the candidate type is a subtype of the target type, narrow to the candidate type.
                // Otherwise, if the target type is assignable to the candidate type, keep the target type.
                // Otherwise, if the candidate type is assignable to the target type, narrow to the candidate
                // type. Otherwise, the types are completely unrelated, so narrow to an intersection of the
                // two types.
                return isTypeSubtypeOf(candidate, type) ? candidate :
                    isTypeAssignableTo(type, candidate) ? type :
                        isTypeAssignableTo(candidate, type) ? candidate :
                            getIntersectionType([type, candidate]);
            }
            function narrowTypeByTypePredicate(type, callExpression, assumeTrue) {
                if (!hasMatchingArgument(callExpression, reference) || !maybeTypePredicateCall(callExpression)) {
                    return type;
                }
                var signature = getResolvedSignature(callExpression);
                var predicate = signature.typePredicate;
                if (!predicate) {
                    return type;
                }
                // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
                if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) {
                    return type;
                }
                if (ts.isIdentifierTypePredicate(predicate)) {
                    var predicateArgument = callExpression.arguments[predicate.parameterIndex - (signature.thisParameter ? 1 : 0)];
                    if (predicateArgument) {
                        if (isMatchingReference(reference, predicateArgument)) {
                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
                        }
                        if (containsMatchingReference(reference, predicateArgument)) {
                            return declaredType;
                        }
                    }
                }
                else {
                    var invokedExpression = ts.skipParentheses(callExpression.expression);
                    if (invokedExpression.kind === 180 /* ElementAccessExpression */ || invokedExpression.kind === 179 /* PropertyAccessExpression */) {
                        var accessExpression = invokedExpression;
                        var possibleReference = ts.skipParentheses(accessExpression.expression);
                        if (isMatchingReference(reference, possibleReference)) {
                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
                        }
                        if (containsMatchingReference(reference, possibleReference)) {
                            return declaredType;
                        }
                    }
                }
                return type;
            }
            // Narrow the given type based on the given expression having the assumed boolean value. The returned type
            // will be a subtype or the same type as the argument.
            function narrowType(type, expr, assumeTrue) {
                switch (expr.kind) {
                    case 71 /* Identifier */:
                    case 99 /* ThisKeyword */:
                    case 97 /* SuperKeyword */:
                    case 179 /* PropertyAccessExpression */:
                        return narrowTypeByTruthiness(type, expr, assumeTrue);
                    case 181 /* CallExpression */:
                        return narrowTypeByTypePredicate(type, expr, assumeTrue);
                    case 185 /* ParenthesizedExpression */:
                        return narrowType(type, expr.expression, assumeTrue);
                    case 194 /* BinaryExpression */:
                        return narrowTypeByBinaryExpression(type, expr, assumeTrue);
                    case 192 /* PrefixUnaryExpression */:
                        if (expr.operator === 51 /* ExclamationToken */) {
                            return narrowType(type, expr.operand, !assumeTrue);
                        }
                        break;
                }
                return type;
            }
        }
        function getTypeOfSymbolAtLocation(symbol, location) {
            symbol = symbol.exportSymbol || symbol;
            // If we have an identifier or a property access at the given location, if the location is
            // an dotted name expression, and if the location is not an assignment target, obtain the type
            // of the expression (which will reflect control flow analysis). If the expression indeed
            // resolved to the given symbol, return the narrowed type.
            if (location.kind === 71 /* Identifier */) {
                if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) {
                    location = location.parent;
                }
                if (ts.isPartOfExpression(location) && !ts.isAssignmentTarget(location)) {
                    var type = getTypeOfExpression(location);
                    if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
                        return type;
                    }
                }
            }
            // The location isn't a reference to the given symbol, meaning we're being asked
            // a hypothetical question of what type the symbol would have if there was a reference
            // to it at the given location. Since we have no control flow information for the
            // hypothetical reference (control flow information is created and attached by the
            // binder), we simply return the declared type of the symbol.
            return getTypeOfSymbol(symbol);
        }
        function getControlFlowContainer(node) {
            return ts.findAncestor(node.parent, function (node) {
                return ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) ||
                    node.kind === 234 /* ModuleBlock */ ||
                    node.kind === 265 /* SourceFile */ ||
                    node.kind === 149 /* PropertyDeclaration */;
            });
        }
        // Check if a parameter is assigned anywhere within its declaring function.
        function isParameterAssigned(symbol) {
            var func = ts.getRootDeclaration(symbol.valueDeclaration).parent;
            var links = getNodeLinks(func);
            if (!(links.flags & 4194304 /* AssignmentsMarked */)) {
                links.flags |= 4194304 /* AssignmentsMarked */;
                if (!hasParentWithAssignmentsMarked(func)) {
                    markParameterAssignments(func);
                }
            }
            return symbol.isAssigned || false;
        }
        function hasParentWithAssignmentsMarked(node) {
            return !!ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !!(getNodeLinks(node).flags & 4194304 /* AssignmentsMarked */); });
        }
        function markParameterAssignments(node) {
            if (node.kind === 71 /* Identifier */) {
                if (ts.isAssignmentTarget(node)) {
                    var symbol = getResolvedSymbol(node);
                    if (symbol.valueDeclaration && ts.getRootDeclaration(symbol.valueDeclaration).kind === 146 /* Parameter */) {
                        symbol.isAssigned = true;
                    }
                }
            }
            else {
                ts.forEachChild(node, markParameterAssignments);
            }
        }
        function isConstVariable(symbol) {
            return symbol.flags & 3 /* Variable */ && (getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType;
        }
        /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
        function removeOptionalityFromDeclaredType(declaredType, declaration) {
            var annotationIncludesUndefined = strictNullChecks &&
                declaration.kind === 146 /* Parameter */ &&
                declaration.initializer &&
                getFalsyFlags(declaredType) & 2048 /* Undefined */ &&
                !(getFalsyFlags(checkExpression(declaration.initializer)) & 2048 /* Undefined */);
            return annotationIncludesUndefined ? getTypeWithFacts(declaredType, 131072 /* NEUndefined */) : declaredType;
        }
        function isApparentTypePosition(node) {
            var parent = node.parent;
            return parent.kind === 179 /* PropertyAccessExpression */ ||
                parent.kind === 181 /* CallExpression */ && parent.expression === node ||
                parent.kind === 180 /* ElementAccessExpression */ && parent.expression === node;
        }
        function typeHasNullableConstraint(type) {
            return type.flags & 540672 /* TypeVariable */ && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, 6144 /* Nullable */);
        }
        function getDeclaredOrApparentType(symbol, node) {
            // When a node is the left hand expression of a property access, element access, or call expression,
            // and the type of the node includes type variables with constraints that are nullable, we fetch the
            // apparent type of the node *before* performing control flow analysis such that narrowings apply to
            // the constraint type.
            var type = getTypeOfSymbol(symbol);
            if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) {
                return mapType(getWidenedType(type), getApparentType);
            }
            return type;
        }
        function checkIdentifier(node) {
            var symbol = getResolvedSymbol(node);
            if (symbol === unknownSymbol) {
                return unknownType;
            }
            // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
            // Although in down-level emit of arrow function, we emit it using function expression which means that
            // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects
            // will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
            // To avoid that we will give an error to users if they use arguments objects in arrow function so that they
            // can explicitly bound arguments objects
            if (symbol === argumentsSymbol) {
                var container = ts.getContainingFunction(node);
                if (languageVersion < 2 /* ES2015 */) {
                    if (container.kind === 187 /* ArrowFunction */) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
                    }
                    else if (ts.hasModifier(container, 256 /* Async */)) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method);
                    }
                }
                getNodeLinks(container).flags |= 8192 /* CaptureArguments */;
                return getTypeOfSymbol(symbol);
            }
            // We should only mark aliases as referenced if there isn't a local value declaration
            // for the symbol.
            if (isNonLocalAlias(symbol, /*excludes*/ 107455 /* Value */) && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
                markAliasSymbolAsReferenced(symbol);
            }
            var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
            var declaration = localOrExportSymbol.valueDeclaration;
            if (localOrExportSymbol.flags & 32 /* Class */) {
                // Due to the emit for class decorators, any reference to the class from inside of the class body
                // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                // behavior of class names in ES6.
                if (declaration.kind === 229 /* ClassDeclaration */
                    && ts.nodeIsDecorated(declaration)) {
                    var container = ts.getContainingClass(node);
                    while (container !== undefined) {
                        if (container === declaration && container.name !== node) {
                            getNodeLinks(declaration).flags |= 8388608 /* ClassWithConstructorReference */;
                            getNodeLinks(node).flags |= 16777216 /* ConstructorReferenceInClass */;
                            break;
                        }
                        container = ts.getContainingClass(container);
                    }
                }
                else if (declaration.kind === 199 /* ClassExpression */) {
                    // When we emit a class expression with static members that contain a reference
                    // to the constructor in the initializer, we will need to substitute that
                    // binding with an alias as the class name is not in scope.
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    while (container !== undefined) {
                        if (container.parent === declaration) {
                            if (container.kind === 149 /* PropertyDeclaration */ && ts.hasModifier(container, 32 /* Static */)) {
                                getNodeLinks(declaration).flags |= 8388608 /* ClassWithConstructorReference */;
                                getNodeLinks(node).flags |= 16777216 /* ConstructorReferenceInClass */;
                            }
                            break;
                        }
                        container = ts.getThisContainer(container, /*includeArrowFunctions*/ false);
                    }
                }
            }
            checkCollisionWithCapturedSuperVariable(node, node);
            checkCollisionWithCapturedThisVariable(node, node);
            checkCollisionWithCapturedNewTargetVariable(node, node);
            checkNestedBlockScopedBinding(node, symbol);
            var type = getDeclaredOrApparentType(localOrExportSymbol, node);
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (assignmentKind) {
                if (!(localOrExportSymbol.flags & 3 /* Variable */)) {
                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol));
                    return unknownType;
                }
                if (isReadonlySymbol(localOrExportSymbol)) {
                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(symbol));
                    return unknownType;
                }
            }
            var isAlias = localOrExportSymbol.flags & 2097152 /* Alias */;
            // We only narrow variables and parameters occurring in a non-assignment position. For all other
            // entities we simply return the declared type.
            if (localOrExportSymbol.flags & 3 /* Variable */) {
                if (assignmentKind === 1 /* Definite */) {
                    return type;
                }
            }
            else if (isAlias) {
                declaration = ts.find(symbol.declarations, isSomeImportDeclaration);
            }
            else {
                return type;
            }
            if (!declaration) {
                return type;
            }
            // The declaration container is the innermost function that encloses the declaration of the variable
            // or parameter. The flow container is the innermost function starting with which we analyze the control
            // flow graph to determine the control flow based type.
            var isParameter = ts.getRootDeclaration(declaration).kind === 146 /* Parameter */;
            var declarationContainer = getControlFlowContainer(declaration);
            var flowContainer = getControlFlowContainer(node);
            var isOuterVariable = flowContainer !== declarationContainer;
            // When the control flow originates in a function expression or arrow function and we are referencing
            // a const variable or parameter from an outer function, we extend the origin of the control flow
            // analysis to include the immediately enclosing function.
            while (flowContainer !== declarationContainer && (flowContainer.kind === 186 /* FunctionExpression */ ||
                flowContainer.kind === 187 /* ArrowFunction */ || ts.isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
                (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
                flowContainer = getControlFlowContainer(flowContainer);
            }
            // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
            // the entire control flow graph from the variable's declaration (i.e. when the flow container and
            // declaration container are the same).
            var assumeInitialized = isParameter || isAlias || isOuterVariable ||
                type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & 1 /* Any */) !== 0 || isInTypeQuery(node) || node.parent.kind === 246 /* ExportSpecifier */) ||
                node.parent.kind === 203 /* NonNullExpression */ ||
                ts.isInAmbientContext(declaration);
            var initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, ts.getRootDeclaration(declaration)) : type) :
                type === autoType || type === autoArrayType ? undefinedType :
                    getNullableType(type, 2048 /* Undefined */);
            var flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
            // A variable is considered uninitialized when it is possible to analyze the entire control flow graph
            // from declaration to use, and when the variable's declared type doesn't include undefined but the
            // control flow based type does include undefined.
            if (type === autoType || type === autoArrayType) {
                if (flowType === autoType || flowType === autoArrayType) {
                    if (noImplicitAny) {
                        error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
                        error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
                    }
                    return convertAutoToAny(flowType);
                }
            }
            else if (!assumeInitialized && !(getFalsyFlags(type) & 2048 /* Undefined */) && getFalsyFlags(flowType) & 2048 /* Undefined */) {
                error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
                // Return the declared type to reduce follow-on errors
                return type;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function isInsideFunction(node, threshold) {
            return !!ts.findAncestor(node, function (n) { return n === threshold ? "quit" : ts.isFunctionLike(n); });
        }
        function checkNestedBlockScopedBinding(node, symbol) {
            if (languageVersion >= 2 /* ES2015 */ ||
                (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 ||
                symbol.valueDeclaration.parent.kind === 260 /* CatchClause */) {
                return;
            }
            // 1. walk from the use site up to the declaration and check
            // if there is anything function like between declaration and use-site (is binding/class is captured in function).
            // 2. walk from the declaration up to the boundary of lexical environment and check
            // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement)
            var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
            var usedInFunction = isInsideFunction(node.parent, container);
            var current = container;
            var containedInIterationStatement = false;
            while (current && !ts.nodeStartsNewLexicalEnvironment(current)) {
                if (ts.isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
                    containedInIterationStatement = true;
                    break;
                }
                current = current.parent;
            }
            if (containedInIterationStatement) {
                if (usedInFunction) {
                    // mark iteration statement as containing block-scoped binding captured in some function
                    getNodeLinks(current).flags |= 65536 /* LoopWithCapturedBlockScopedBinding */;
                }
                // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement.
                // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back.
                if (container.kind === 214 /* ForStatement */ &&
                    ts.getAncestor(symbol.valueDeclaration, 227 /* VariableDeclarationList */).parent === container &&
                    isAssignedInBodyOfForStatement(node, container)) {
                    getNodeLinks(symbol.valueDeclaration).flags |= 2097152 /* NeedsLoopOutParameter */;
                }
                // set 'declared inside loop' bit on the block-scoped binding
                getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* BlockScopedBindingInLoop */;
            }
            if (usedInFunction) {
                getNodeLinks(symbol.valueDeclaration).flags |= 131072 /* CapturedBlockScopedBinding */;
            }
        }
        function isAssignedInBodyOfForStatement(node, container) {
            // skip parenthesized nodes
            var current = node;
            while (current.parent.kind === 185 /* ParenthesizedExpression */) {
                current = current.parent;
            }
            // check if node is used as LHS in some assignment expression
            var isAssigned = false;
            if (ts.isAssignmentTarget(current)) {
                isAssigned = true;
            }
            else if ((current.parent.kind === 192 /* PrefixUnaryExpression */ || current.parent.kind === 193 /* PostfixUnaryExpression */)) {
                var expr = current.parent;
                isAssigned = expr.operator === 43 /* PlusPlusToken */ || expr.operator === 44 /* MinusMinusToken */;
            }
            if (!isAssigned) {
                return false;
            }
            // at this point we know that node is the target of assignment
            // now check that modification happens inside the statement part of the ForStatement
            return !!ts.findAncestor(current, function (n) { return n === container ? "quit" : n === container.statement; });
        }
        function captureLexicalThis(node, container) {
            getNodeLinks(node).flags |= 2 /* LexicalThis */;
            if (container.kind === 149 /* PropertyDeclaration */ || container.kind === 152 /* Constructor */) {
                var classNode = container.parent;
                getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
            }
            else {
                getNodeLinks(container).flags |= 4 /* CaptureThis */;
            }
        }
        function findFirstSuperCall(n) {
            if (ts.isSuperCall(n)) {
                return n;
            }
            else if (ts.isFunctionLike(n)) {
                return undefined;
            }
            return ts.forEachChild(n, findFirstSuperCall);
        }
        /**
         * Return a cached result if super-statement is already found.
         * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
         *
         * @param constructor constructor-function to look for super statement
         */
        function getSuperCallInConstructor(constructor) {
            var links = getNodeLinks(constructor);
            // Only trying to find super-call if we haven't yet tried to find one.  Once we try, we will record the result
            if (links.hasSuperCall === undefined) {
                links.superCall = findFirstSuperCall(constructor.body);
                links.hasSuperCall = links.superCall ? true : false;
            }
            return links.superCall;
        }
        /**
         * Check if the given class-declaration extends null then return true.
         * Otherwise, return false
         * @param classDecl a class declaration to check if it extends null
         */
        function classDeclarationExtendsNull(classDecl) {
            var classSymbol = getSymbolOfNode(classDecl);
            var classInstanceType = getDeclaredTypeOfSymbol(classSymbol);
            var baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
            return baseConstructorType === nullWideningType;
        }
        function checkThisBeforeSuper(node, container, diagnosticMessage) {
            var containingClassDecl = container.parent;
            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(containingClassDecl);
            // If a containing class does not have extends clause or the class extends null
            // skip checking whether super statement is called before "this" accessing.
            if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) {
                var superCall = getSuperCallInConstructor(container);
                // We should give an error in the following cases:
                //      - No super-call
                //      - "this" is accessing before super-call.
                //          i.e super(this)
                //              this.x; super();
                // We want to make sure that super-call is done before accessing "this" so that
                // "this" is not accessed as a parameter of the super-call.
                if (!superCall || superCall.end > node.pos) {
                    // In ES6, super inside constructor of class-declaration has to precede "this" accessing
                    error(node, diagnosticMessage);
                }
            }
        }
        function checkThisExpression(node) {
            // Stop at the first arrow function so that we can
            // tell whether 'this' needs to be captured.
            var container = ts.getThisContainer(node, /* includeArrowFunctions */ true);
            var needToCaptureLexicalThis = false;
            if (container.kind === 152 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
            }
            // Now skip arrow functions to get the "real" owner of 'this'.
            if (container.kind === 187 /* ArrowFunction */) {
                container = ts.getThisContainer(container, /* includeArrowFunctions */ false);
                // When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code
                needToCaptureLexicalThis = (languageVersion < 2 /* ES2015 */);
            }
            switch (container.kind) {
                case 233 /* ModuleDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 232 /* EnumDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 152 /* Constructor */:
                    if (isInConstructorArgumentInitializer(node, container)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    if (ts.hasModifier(container, 32 /* Static */)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 144 /* ComputedPropertyName */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
                    break;
            }
            if (needToCaptureLexicalThis) {
                captureLexicalThis(node, container);
            }
            if (ts.isFunctionLike(container) &&
                (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) {
                // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
                // If this is a function in a JS file, it might be a class method. Check if it's the RHS
                // of a x.prototype.y = function [name]() { .... }
                if (container.kind === 186 /* FunctionExpression */ &&
                    container.parent.kind === 194 /* BinaryExpression */ &&
                    ts.getSpecialPropertyAssignmentKind(container.parent) === 3 /* PrototypeProperty */) {
                    // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
                    var className = container.parent // x.prototype.y = f
                        .left // x.prototype.y
                        .expression // x.prototype
                        .expression; // x
                    var classSymbol = checkExpression(className).symbol;
                    if (classSymbol && classSymbol.members && (classSymbol.flags & 16 /* Function */)) {
                        return getInferredClassType(classSymbol);
                    }
                }
                var thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
                if (thisType) {
                    return thisType;
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                var type = ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
                return getFlowTypeOfReference(node, type);
            }
            if (ts.isInJavaScriptFile(node)) {
                var type = getTypeForThisExpressionFromJSDoc(container);
                if (type && type !== unknownType) {
                    return type;
                }
            }
            if (noImplicitThis) {
                // With noImplicitThis, functions may not reference 'this' if it has type 'any'
                error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
            }
            return anyType;
        }
        function getTypeForThisExpressionFromJSDoc(node) {
            var jsdocType = ts.getJSDocType(node);
            if (jsdocType && jsdocType.kind === 273 /* JSDocFunctionType */) {
                var jsDocFunctionType = jsdocType;
                if (jsDocFunctionType.parameters.length > 0 &&
                    jsDocFunctionType.parameters[0].name &&
                    jsDocFunctionType.parameters[0].name.escapedText === "this") {
                    return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
                }
            }
        }
        function isInConstructorArgumentInitializer(node, constructorDecl) {
            return !!ts.findAncestor(node, function (n) { return n === constructorDecl ? "quit" : n.kind === 146 /* Parameter */; });
        }
        function checkSuperExpression(node) {
            var isCallExpression = node.parent.kind === 181 /* CallExpression */ && node.parent.expression === node;
            var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true);
            var needToCaptureLexicalThis = false;
            // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting
            if (!isCallExpression) {
                while (container && container.kind === 187 /* ArrowFunction */) {
                    container = ts.getSuperContainer(container, /*stopOnFunctions*/ true);
                    needToCaptureLexicalThis = languageVersion < 2 /* ES2015 */;
                }
            }
            var canUseSuperExpression = isLegalUsageOfSuperExpression(container);
            var nodeCheckFlag = 0;
            if (!canUseSuperExpression) {
                // issue more specific error if super is used in computed property name
                // class A { foo() { return "1" }}
                // class B {
                //     [super.foo()]() {}
                // }
                var current = ts.findAncestor(node, function (n) { return n === container ? "quit" : n.kind === 144 /* ComputedPropertyName */; });
                if (current && current.kind === 144 /* ComputedPropertyName */) {
                    error(node, ts.Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
                }
                else if (isCallExpression) {
                    error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
                }
                else if (!container || !container.parent || !(ts.isClassLike(container.parent) || container.parent.kind === 178 /* ObjectLiteralExpression */)) {
                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions);
                }
                else {
                    error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
                }
                return unknownType;
            }
            if (!isCallExpression && container.kind === 152 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
            }
            if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) {
                nodeCheckFlag = 512 /* SuperStatic */;
            }
            else {
                nodeCheckFlag = 256 /* SuperInstance */;
            }
            getNodeLinks(node).flags |= nodeCheckFlag;
            // Due to how we emit async functions, we need to specialize the emit for an async method that contains a `super` reference.
            // This is due to the fact that we emit the body of an async function inside of a generator function. As generator
            // functions cannot reference `super`, we emit a helper inside of the method body, but outside of the generator. This helper
            // uses an arrow function, which is permitted to reference `super`.
            //
            // There are two primary ways we can access `super` from within an async method. The first is getting the value of a property
            // or indexed access on super, either as part of a right-hand-side expression or call expression. The second is when setting the value
            // of a property or indexed access, either as part of an assignment expression or destructuring assignment.
            //
            // The simplest case is reading a value, in which case we will emit something like the following:
            //
            //  // ts
            //  ...
            //  async asyncMethod() {
            //    let x = await super.asyncMethod();
            //    return x;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod() {
            //      const _super = name => super[name];
            //      return __awaiter(this, arguments, Promise, function *() {
            //          let x = yield _super("asyncMethod").call(this);
            //          return x;
            //      });
            //  }
            //  ...
            //
            // The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
            // are legal in ES6, but also likely less frequent, we emit the same more complex helper for both scenarios:
            //
            //  // ts
            //  ...
            //  async asyncMethod(ar: Promise<any[]>) {
            //      [super.a, super.b] = await ar;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod(ar) {
            //      const _super = (function (geti, seti) {
            //          const cache = Object.create(null);
            //          return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
            //      })(name => super[name], (name, value) => super[name] = value);
            //      return __awaiter(this, arguments, Promise, function *() {
            //          [_super("a").value, _super("b").value] = yield ar;
            //      });
            //  }
            //  ...
            //
            // This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set.
            // This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment
            // while a property access can.
            if (container.kind === 151 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) {
                if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) {
                    getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */;
                }
                else {
                    getNodeLinks(container).flags |= 2048 /* AsyncMethodWithSuper */;
                }
            }
            if (needToCaptureLexicalThis) {
                // call expressions are allowed only in constructors so they should always capture correct 'this'
                // super property access expressions can also appear in arrow functions -
                // in this case they should also use correct lexical this
                captureLexicalThis(node.parent, container);
            }
            if (container.parent.kind === 178 /* ObjectLiteralExpression */) {
                if (languageVersion < 2 /* ES2015 */) {
                    error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher);
                    return unknownType;
                }
                else {
                    // for object literal assume that type of 'super' is 'any'
                    return anyType;
                }
            }
            // at this point the only legal case for parent is ClassLikeDeclaration
            var classLikeDeclaration = container.parent;
            var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration));
            var baseClassType = classType && getBaseTypes(classType)[0];
            if (!baseClassType) {
                if (!ts.getClassExtendsHeritageClauseElement(classLikeDeclaration)) {
                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class);
                }
                return unknownType;
            }
            if (container.kind === 152 /* Constructor */ && isInConstructorArgumentInitializer(node, container)) {
                // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
                error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
                return unknownType;
            }
            return nodeCheckFlag === 512 /* SuperStatic */
                ? getBaseConstructorTypeOfClass(classType)
                : getTypeWithThisArgument(baseClassType, classType.thisType);
            function isLegalUsageOfSuperExpression(container) {
                if (!container) {
                    return false;
                }
                if (isCallExpression) {
                    // TS 1.0 SPEC (April 2014): 4.8.1
                    // Super calls are only permitted in constructors of derived classes
                    return container.kind === 152 /* Constructor */;
                }
                else {
                    // TS 1.0 SPEC (April 2014)
                    // 'super' property access is allowed
                    // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
                    // - In a static member function or static member accessor
                    // topmost container must be something that is directly nested in the class declaration\object literal expression
                    if (ts.isClassLike(container.parent) || container.parent.kind === 178 /* ObjectLiteralExpression */) {
                        if (ts.hasModifier(container, 32 /* Static */)) {
                            return container.kind === 151 /* MethodDeclaration */ ||
                                container.kind === 150 /* MethodSignature */ ||
                                container.kind === 153 /* GetAccessor */ ||
                                container.kind === 154 /* SetAccessor */;
                        }
                        else {
                            return container.kind === 151 /* MethodDeclaration */ ||
                                container.kind === 150 /* MethodSignature */ ||
                                container.kind === 153 /* GetAccessor */ ||
                                container.kind === 154 /* SetAccessor */ ||
                                container.kind === 149 /* PropertyDeclaration */ ||
                                container.kind === 148 /* PropertySignature */ ||
                                container.kind === 152 /* Constructor */;
                        }
                    }
                }
                return false;
            }
        }
        function getContainingObjectLiteral(func) {
            return (func.kind === 151 /* MethodDeclaration */ ||
                func.kind === 153 /* GetAccessor */ ||
                func.kind === 154 /* SetAccessor */) && func.parent.kind === 178 /* ObjectLiteralExpression */ ? func.parent :
                func.kind === 186 /* FunctionExpression */ && func.parent.kind === 261 /* PropertyAssignment */ ? func.parent.parent :
                    undefined;
        }
        function getThisTypeArgument(type) {
            return getObjectFlags(type) & 4 /* Reference */ && type.target === globalThisType ? type.typeArguments[0] : undefined;
        }
        function getThisTypeFromContextualType(type) {
            return mapType(type, function (t) {
                return t.flags & 131072 /* Intersection */ ? ts.forEach(t.types, getThisTypeArgument) : getThisTypeArgument(t);
            });
        }
        function getContextualThisParameterType(func) {
            if (func.kind === 187 /* ArrowFunction */) {
                return undefined;
            }
            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                var contextualSignature = getContextualSignature(func);
                if (contextualSignature) {
                    var thisParameter = contextualSignature.thisParameter;
                    if (thisParameter) {
                        return getTypeOfSymbol(thisParameter);
                    }
                }
            }
            var inJs = ts.isInJavaScriptFile(func);
            if (noImplicitThis || inJs) {
                var containingLiteral = getContainingObjectLiteral(func);
                if (containingLiteral) {
                    // We have an object literal method. Check if the containing object literal has a contextual type
                    // that includes a ThisType<T>. If so, T is the contextual type for 'this'. We continue looking in
                    // any directly enclosing object literals.
                    var contextualType = getApparentTypeOfContextualType(containingLiteral);
                    var literal = containingLiteral;
                    var type = contextualType;
                    while (type) {
                        var thisType = getThisTypeFromContextualType(type);
                        if (thisType) {
                            return instantiateType(thisType, getContextualMapper(containingLiteral));
                        }
                        if (literal.parent.kind !== 261 /* PropertyAssignment */) {
                            break;
                        }
                        literal = literal.parent.parent;
                        type = getApparentTypeOfContextualType(literal);
                    }
                    // There was no contextual ThisType<T> for the containing object literal, so the contextual type
                    // for 'this' is the non-null form of the contextual type for the containing object literal or
                    // the type of the object literal itself.
                    return contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral);
                }
                // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
                // contextual type for 'this' is 'obj'.
                var parent = func.parent;
                if (parent.kind === 194 /* BinaryExpression */ && parent.operatorToken.kind === 58 /* EqualsToken */) {
                    var target = parent.left;
                    if (target.kind === 179 /* PropertyAccessExpression */ || target.kind === 180 /* ElementAccessExpression */) {
                        var expression = target.expression;
                        // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }`
                        if (inJs && ts.isIdentifier(expression)) {
                            var sourceFile = ts.getSourceFileOfNode(parent);
                            if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) {
                                return undefined;
                            }
                        }
                        return checkExpressionCached(expression);
                    }
                }
            }
            return undefined;
        }
        // Return contextual type of parameter or undefined if no contextual type is available
        function getContextuallyTypedParameterType(parameter) {
            var func = parameter.parent;
            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                var iife = ts.getImmediatelyInvokedFunctionExpression(func);
                if (iife && iife.arguments) {
                    var indexOfParameter = ts.indexOf(func.parameters, parameter);
                    if (parameter.dotDotDotToken) {
                        var restTypes = [];
                        for (var i = indexOfParameter; i < iife.arguments.length; i++) {
                            restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
                        }
                        return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
                    }
                    var links = getNodeLinks(iife);
                    var cached = links.resolvedSignature;
                    links.resolvedSignature = anySignature;
                    var type = indexOfParameter < iife.arguments.length ?
                        getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
                        parameter.initializer ? undefined : undefinedWideningType;
                    links.resolvedSignature = cached;
                    return type;
                }
                var contextualSignature = getContextualSignature(func);
                if (contextualSignature) {
                    var funcHasRestParameters = ts.hasRestParameter(func);
                    var len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
                    var indexOfParameter = ts.indexOf(func.parameters, parameter);
                    if (ts.getThisParameter(func) !== undefined && !contextualSignature.thisParameter) {
                        ts.Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`.
                        indexOfParameter -= 1;
                    }
                    if (indexOfParameter < len) {
                        return getTypeAtPosition(contextualSignature, indexOfParameter);
                    }
                    // If last parameter is contextually rest parameter get its type
                    if (funcHasRestParameters &&
                        indexOfParameter === (func.parameters.length - 1) &&
                        isRestParameterIndex(contextualSignature, func.parameters.length - 1)) {
                        return getTypeOfSymbol(ts.lastOrUndefined(contextualSignature.parameters));
                    }
                }
            }
            return undefined;
        }
        // In a variable, parameter or property declaration with a type annotation,
        //   the contextual type of an initializer expression is the type of the variable, parameter or property.
        // Otherwise, in a parameter declaration of a contextually typed function expression,
        //   the contextual type of an initializer expression is the contextual type of the parameter.
        // Otherwise, in a variable or parameter declaration with a binding pattern name,
        //   the contextual type of an initializer expression is the type implied by the binding pattern.
        // Otherwise, in a binding pattern inside a variable or parameter declaration,
        //   the contextual type of an initializer expression is the type annotation of the containing declaration, if present.
        function getContextualTypeForInitializerExpression(node) {
            var declaration = node.parent;
            if (node === declaration.initializer) {
                var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
                if (typeNode) {
                    return getTypeFromTypeNode(typeNode);
                }
                if (declaration.kind === 146 /* Parameter */) {
                    var type = getContextuallyTypedParameterType(declaration);
                    if (type) {
                        return type;
                    }
                }
                if (ts.isBindingPattern(declaration.name)) {
                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
                }
                if (ts.isBindingPattern(declaration.parent)) {
                    var parentDeclaration = declaration.parent.parent;
                    var name = declaration.propertyName || declaration.name;
                    if (parentDeclaration.kind !== 176 /* BindingElement */) {
                        var parentTypeNode = ts.getEffectiveTypeAnnotationNode(parentDeclaration);
                        if (parentTypeNode && !ts.isBindingPattern(name)) {
                            var text = ts.getTextOfPropertyName(name);
                            if (text) {
                                return getTypeOfPropertyOfType(getTypeFromTypeNode(parentTypeNode), text);
                            }
                        }
                    }
                }
            }
            return undefined;
        }
        function getContextualTypeForReturnExpression(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                if (functionFlags & 1 /* Generator */) {
                    return undefined;
                }
                var contextualReturnType = getContextualReturnType(func);
                return functionFlags & 2 /* Async */
                    ? contextualReturnType && getAwaitedTypeOfPromise(contextualReturnType) // Async function
                    : contextualReturnType; // Regular function
            }
            return undefined;
        }
        function getContextualTypeForYieldOperand(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    return node.asteriskToken
                        ? contextualReturnType
                        : getIteratedTypeOfGenerator(contextualReturnType, (functionFlags & 2 /* Async */) !== 0);
                }
            }
            return undefined;
        }
        function isInParameterInitializerBeforeContainingFunction(node) {
            while (node.parent && !ts.isFunctionLike(node.parent)) {
                if (node.parent.kind === 146 /* Parameter */ && node.parent.initializer === node) {
                    return true;
                }
                node = node.parent;
            }
            return false;
        }
        function getContextualReturnType(functionDecl) {
            // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
            // corresponding set accessor has a type annotation, return statements in the function are contextually typed
            if (functionDecl.kind === 152 /* Constructor */ ||
                ts.getEffectiveReturnTypeNode(functionDecl) ||
                isGetAccessorWithAnnotatedSetAccessor(functionDecl)) {
                return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
            }
            // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
            // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
            var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                return getReturnTypeOfSignature(signature);
            }
            return undefined;
        }
        // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter.
        function getContextualTypeForArgument(callTarget, arg) {
            var args = getEffectiveCallArguments(callTarget);
            var argIndex = ts.indexOf(args, arg);
            if (argIndex >= 0) {
                // If we're already in the process of resolving the given signature, don't resolve again as
                // that could cause infinite recursion. Instead, return anySignature.
                var signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget);
                return getTypeAtPosition(signature, argIndex);
            }
            return undefined;
        }
        function getContextualTypeForSubstitutionExpression(template, substitutionExpression) {
            if (template.parent.kind === 183 /* TaggedTemplateExpression */) {
                return getContextualTypeForArgument(template.parent, substitutionExpression);
            }
            return undefined;
        }
        function getContextualTypeForBinaryOperand(node) {
            var binaryExpression = node.parent;
            var operator = binaryExpression.operatorToken.kind;
            if (ts.isAssignmentOperator(operator)) {
                if (node === binaryExpression.right) {
                    // Don't do this for special property assignments to avoid circularity
                    switch (ts.getSpecialPropertyAssignmentKind(binaryExpression)) {
                        case 0 /* None */:
                            break;
                        case 5 /* Property */:
                            // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
                            // See `bindStaticPropertyAssignment` in `binder.ts`.
                            if (!binaryExpression.left.symbol) {
                                break;
                            }
                        // falls through
                        case 1 /* ExportsProperty */:
                        case 2 /* ModuleExports */:
                        case 3 /* PrototypeProperty */:
                        case 4 /* ThisProperty */:
                            return undefined;
                    }
                    // In an assignment expression, the right operand is contextually typed by the type of the left operand.
                    return getTypeOfExpression(binaryExpression.left);
                }
            }
            else if (operator === 54 /* BarBarToken */) {
                // When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
                // expression has no contextual type, the right operand is contextually typed by the type of the left operand.
                var type = getContextualType(binaryExpression);
                if (!type && node === binaryExpression.right) {
                    type = getTypeOfExpression(binaryExpression.left, /*cache*/ true);
                }
                return type;
            }
            else if (operator === 53 /* AmpersandAmpersandToken */ || operator === 26 /* CommaToken */) {
                if (node === binaryExpression.right) {
                    return getContextualType(binaryExpression);
                }
            }
            return undefined;
        }
        function getTypeOfPropertyOfContextualType(type, name) {
            return mapType(type, function (t) {
                var prop = t.flags & 229376 /* StructuredType */ ? getPropertyOfType(t, name) : undefined;
                return prop ? getTypeOfSymbol(prop) : undefined;
            });
        }
        function getIndexTypeOfContextualType(type, kind) {
            return mapType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); });
        }
        // Return true if the given contextual type is a tuple-like type
        function contextualTypeIsTupleLikeType(type) {
            return !!(type.flags & 65536 /* Union */ ? ts.forEach(type.types, isTupleLikeType) : isTupleLikeType(type));
        }
        // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of
        // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one
        // exists. Otherwise, it is the type of the string index signature in T, if one exists.
        function getContextualTypeForObjectLiteralMethod(node) {
            ts.Debug.assert(ts.isObjectLiteralMethod(node));
            if (isInsideWithStatementBody(node)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            return getContextualTypeForObjectLiteralElement(node);
        }
        function getContextualTypeForObjectLiteralElement(element) {
            var objectLiteral = element.parent;
            var type = getApparentTypeOfContextualType(objectLiteral);
            if (type) {
                if (!ts.hasDynamicName(element)) {
                    // For a (non-symbol) computed property, there is no reason to look up the name
                    // in the type. It will just be "__computed", which does not appear in any
                    // SymbolTable.
                    var symbolName_1 = getSymbolOfNode(element).escapedName;
                    var propertyType = getTypeOfPropertyOfContextualType(type, symbolName_1);
                    if (propertyType) {
                        return propertyType;
                    }
                }
                return isNumericName(element.name) && getIndexTypeOfContextualType(type, 1 /* Number */) ||
                    getIndexTypeOfContextualType(type, 0 /* String */);
            }
            return undefined;
        }
        // In an array literal contextually typed by a type T, the contextual type of an element expression at index N is
        // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature,
        // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
        // type of T.
        function getContextualTypeForElementExpression(arrayContextualType, index) {
            return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index)
                || getIndexTypeOfContextualType(arrayContextualType, 1 /* Number */)
                || getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false));
        }
        // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type.
        function getContextualTypeForConditionalOperand(node) {
            var conditional = node.parent;
            return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
        }
        function getContextualTypeForJsxExpression(node) {
            // JSX expression can appear in two position : JSX Element's children or JSX attribute
            var jsxAttributes = ts.isJsxAttributeLike(node.parent) ?
                node.parent.parent :
                node.parent.openingElement.attributes; // node.parent is JsxElement
            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
            // which is a type of the parameter of the signature we are trying out.
            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
            var attributesType = getContextualType(jsxAttributes);
            if (!attributesType || isTypeAny(attributesType)) {
                return undefined;
            }
            if (ts.isJsxAttribute(node.parent)) {
                // JSX expression is in JSX attribute
                return getTypeOfPropertyOfContextualType(attributesType, node.parent.name.escapedText);
            }
            else if (node.parent.kind === 249 /* JsxElement */) {
                // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
                var jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
                return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : anyType;
            }
            else {
                // JSX expression is in JSX spread attribute
                return attributesType;
            }
        }
        function getContextualTypeForJsxAttribute(attribute) {
            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
            // which is a type of the parameter of the signature we are trying out.
            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
            var attributesType = getContextualType(attribute.parent);
            if (ts.isJsxAttribute(attribute)) {
                if (!attributesType || isTypeAny(attributesType)) {
                    return undefined;
                }
                return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText);
            }
            else {
                return attributesType;
            }
        }
        // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
        // be "pushed" onto a node using the contextualType property.
        function getApparentTypeOfContextualType(node) {
            var type = getContextualType(node);
            return type && getApparentType(type);
        }
        /**
         * Woah! Do you really want to use this function?
         *
         * Unless you're trying to get the *non-apparent* type for a
         * value-literal type or you're authoring relevant portions of this algorithm,
         * you probably meant to use 'getApparentTypeOfContextualType'.
         * Otherwise this may not be very useful.
         *
         * In cases where you *are* working on this function, you should understand
         * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContextualType'.
         *
         *   - Use 'getContextualType' when you are simply going to propagate the result to the expression.
         *   - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
         *
         * @param node the expression whose contextual type will be returned.
         * @returns the contextual type of an expression.
         */
        function getContextualType(node) {
            if (isInsideWithStatementBody(node)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (node.contextualType) {
                return node.contextualType;
            }
            var parent = node.parent;
            switch (parent.kind) {
                case 226 /* VariableDeclaration */:
                case 146 /* Parameter */:
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                case 176 /* BindingElement */:
                    return getContextualTypeForInitializerExpression(node);
                case 187 /* ArrowFunction */:
                case 219 /* ReturnStatement */:
                    return getContextualTypeForReturnExpression(node);
                case 197 /* YieldExpression */:
                    return getContextualTypeForYieldOperand(parent);
                case 181 /* CallExpression */:
                case 182 /* NewExpression */:
                    return getContextualTypeForArgument(parent, node);
                case 184 /* TypeAssertionExpression */:
                case 202 /* AsExpression */:
                    return getTypeFromTypeNode(parent.type);
                case 194 /* BinaryExpression */:
                    return getContextualTypeForBinaryOperand(node);
                case 261 /* PropertyAssignment */:
                case 262 /* ShorthandPropertyAssignment */:
                    return getContextualTypeForObjectLiteralElement(parent);
                case 263 /* SpreadAssignment */:
                    return getApparentTypeOfContextualType(parent.parent);
                case 177 /* ArrayLiteralExpression */: {
                    var arrayLiteral = parent;
                    var type = getApparentTypeOfContextualType(arrayLiteral);
                    return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node));
                }
                case 195 /* ConditionalExpression */:
                    return getContextualTypeForConditionalOperand(node);
                case 205 /* TemplateSpan */:
                    ts.Debug.assert(parent.parent.kind === 196 /* TemplateExpression */);
                    return getContextualTypeForSubstitutionExpression(parent.parent, node);
                case 185 /* ParenthesizedExpression */: {
                    // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
                    var tag = ts.isInJavaScriptFile(parent) ? ts.getJSDocTypeTag(parent) : undefined;
                    return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent);
                }
                case 256 /* JsxExpression */:
                    return getContextualTypeForJsxExpression(parent);
                case 253 /* JsxAttribute */:
                case 255 /* JsxSpreadAttribute */:
                    return getContextualTypeForJsxAttribute(parent);
                case 251 /* JsxOpeningElement */:
                case 250 /* JsxSelfClosingElement */:
                    return getAttributesTypeFromJsxOpeningLikeElement(parent);
            }
            return undefined;
        }
        function getContextualMapper(node) {
            node = ts.findAncestor(node, function (n) { return !!n.contextualMapper; });
            return node ? node.contextualMapper : identityMapper;
        }
        // If the given type is an object or union type with a single signature, and if that signature has at
        // least as many parameters as the given function, return the signature. Otherwise return undefined.
        function getContextualCallSignature(type, node) {
            var signatures = getSignaturesOfStructuredType(type, 0 /* Call */);
            if (signatures.length === 1) {
                var signature = signatures[0];
                if (!isAritySmaller(signature, node)) {
                    return signature;
                }
            }
        }
        /** If the contextual signature has fewer parameters than the function expression, do not use it */
        function isAritySmaller(signature, target) {
            var targetParameterCount = 0;
            for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
                var param = target.parameters[targetParameterCount];
                if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
                    break;
                }
            }
            if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) {
                targetParameterCount--;
            }
            var sourceLength = signature.hasRestParameter ? Number.MAX_VALUE : signature.parameters.length;
            return sourceLength < targetParameterCount;
        }
        function isFunctionExpressionOrArrowFunction(node) {
            return node.kind === 186 /* FunctionExpression */ || node.kind === 187 /* ArrowFunction */;
        }
        function getContextualSignatureForFunctionLikeDeclaration(node) {
            // Only function expressions, arrow functions, and object literal methods are contextually typed.
            return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node)
                ? getContextualSignature(node)
                : undefined;
        }
        function getContextualTypeForFunctionLikeDeclaration(node) {
            return ts.isObjectLiteralMethod(node) ?
                getContextualTypeForObjectLiteralMethod(node) :
                getApparentTypeOfContextualType(node);
        }
        // Return the contextual signature for a given expression node. A contextual type provides a
        // contextual signature if it has a single call signature and if that call signature is non-generic.
        // If the contextual type is a union type, get the signature from each type possible and if they are
        // all identical ignoring their return type, the result is same signature but with return type as
        // union type of return types from these signatures
        function getContextualSignature(node) {
            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var type = getContextualTypeForFunctionLikeDeclaration(node);
            if (!type) {
                return undefined;
            }
            if (!(type.flags & 65536 /* Union */)) {
                return getContextualCallSignature(type, node);
            }
            var signatureList;
            var types = type.types;
            for (var _i = 0, types_16 = types; _i < types_16.length; _i++) {
                var current = types_16[_i];
                var signature = getContextualCallSignature(current, node);
                if (signature) {
                    if (!signatureList) {
                        // This signature will contribute to contextual union signature
                        signatureList = [signature];
                    }
                    else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
                        // Signatures aren't identical, do not use
                        return undefined;
                    }
                    else {
                        // Use this signature for contextual union signature
                        signatureList.push(signature);
                    }
                }
            }
            // Result is union of signatures collected (return type is union of return types of this signature set)
            var result;
            if (signatureList) {
                result = cloneSignature(signatureList[0]);
                // Clear resolved return type we possibly got from cloneSignature
                result.resolvedReturnType = undefined;
                result.unionSignatures = signatureList;
            }
            return result;
        }
        function checkSpreadExpression(node, checkMode) {
            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                checkExternalEmitHelpers(node, 1536 /* SpreadIncludes */);
            }
            var arrayOrIterableType = checkExpression(node.expression, checkMode);
            return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterables*/ false);
        }
        function hasDefaultValue(node) {
            return (node.kind === 176 /* BindingElement */ && !!node.initializer) ||
                (node.kind === 194 /* BinaryExpression */ && node.operatorToken.kind === 58 /* EqualsToken */);
        }
        function checkArrayLiteral(node, checkMode) {
            var elements = node.elements;
            var hasSpreadElement = false;
            var elementTypes = [];
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            var contextualType = getApparentTypeOfContextualType(node);
            for (var index = 0; index < elements.length; index++) {
                var e = elements[index];
                if (inDestructuringPattern && e.kind === 198 /* SpreadElement */) {
                    // Given the following situation:
                    //    var c: {};
                    //    [...c] = ["", 0];
                    //
                    // c is represented in the tree as a spread element in an array literal.
                    // But c really functions as a rest element, and its purpose is to provide
                    // a contextual type for the right hand side of the assignment. Therefore,
                    // instead of calling checkExpression on "...c", which will give an error
                    // if c is not iterable/array-like, we need to act as if we are trying to
                    // get the contextual element type from it. So we do something similar to
                    // getContextualTypeForElementExpression, which will crucially not error
                    // if there is no index type / iterated type.
                    var restArrayType = checkExpression(e.expression, checkMode);
                    var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) ||
                        getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false);
                    if (restElementType) {
                        elementTypes.push(restElementType);
                    }
                }
                else {
                    var elementContextualType = getContextualTypeForElementExpression(contextualType, index);
                    var type = checkExpressionForMutableLocation(e, checkMode, elementContextualType);
                    elementTypes.push(type);
                }
                hasSpreadElement = hasSpreadElement || e.kind === 198 /* SpreadElement */;
            }
            if (!hasSpreadElement) {
                // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
                // that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
                if (inDestructuringPattern && elementTypes.length) {
                    var type = cloneTypeReference(createTupleType(elementTypes));
                    type.pattern = node;
                    return type;
                }
                var contextualType_1 = getApparentTypeOfContextualType(node);
                if (contextualType_1 && contextualTypeIsTupleLikeType(contextualType_1)) {
                    var pattern = contextualType_1.pattern;
                    // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
                    // tuple type with the corresponding binding or assignment element types to make the lengths equal.
                    if (pattern && (pattern.kind === 175 /* ArrayBindingPattern */ || pattern.kind === 177 /* ArrayLiteralExpression */)) {
                        var patternElements = pattern.elements;
                        for (var i = elementTypes.length; i < patternElements.length; i++) {
                            var patternElement = patternElements[i];
                            if (hasDefaultValue(patternElement)) {
                                elementTypes.push(contextualType_1.typeArguments[i]);
                            }
                            else {
                                if (patternElement.kind !== 200 /* OmittedExpression */) {
                                    error(patternElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
                                }
                                elementTypes.push(unknownType);
                            }
                        }
                    }
                    if (elementTypes.length) {
                        return createTupleType(elementTypes);
                    }
                }
            }
            return createArrayType(elementTypes.length ?
                getUnionType(elementTypes, /*subtypeReduction*/ true) :
                strictNullChecks ? neverType : undefinedWideningType);
        }
        function isNumericName(name) {
            switch (name.kind) {
                case 144 /* ComputedPropertyName */:
                    return isNumericComputedName(name);
                case 71 /* Identifier */:
                    return isNumericLiteralName(name.escapedText);
                case 8 /* NumericLiteral */:
                case 9 /* StringLiteral */:
                    return isNumericLiteralName(name.text);
                default:
                    return false;
            }
        }
        function isNumericComputedName(name) {
            // It seems odd to consider an expression of type Any to result in a numeric name,
            // but this behavior is consistent with checkIndexedAccess
            return isTypeAssignableToKind(checkComputedPropertyName(name), 84 /* NumberLike */);
        }
        function isInfinityOrNaNString(name) {
            return name === "Infinity" || name === "-Infinity" || name === "NaN";
        }
        function isNumericLiteralName(name) {
            // The intent of numeric names is that
            //     - they are names with text in a numeric form, and that
            //     - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit',
            //         acquired by applying the abstract 'ToNumber' operation on the name's text.
            //
            // The subtlety is in the latter portion, as we cannot reliably say that anything that looks like a numeric literal is a numeric name.
            // In fact, it is the case that the text of the name must be equal to 'ToString(numLit)' for this to hold.
            //
            // Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)'
            // according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'.
            // Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names
            // because their 'ToString' representation is not equal to their original text.
            // This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1.
            //
            // Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'.
            // The '+' prefix operator is equivalent here to applying the abstract ToNumber operation.
            // Applying the 'toString()' method on a number gives us the abstract ToString operation on a number.
            //
            // Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional.
            // This is desired behavior, because when indexing with them as numeric entities, you are indexing
            // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively.
            return (+name).toString() === name;
        }
        function checkComputedPropertyName(node) {
            var links = getNodeLinks(node.expression);
            if (!links.resolvedType) {
                links.resolvedType = checkExpression(node.expression);
                // This will allow types number, string, symbol or any. It will also allow enums, the unknown
                // type, and any union of these types (like string | number).
                if (links.resolvedType.flags & 6144 /* Nullable */ ||
                    !isTypeAssignableToKind(links.resolvedType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */) &&
                        !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) {
                    error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
                }
                else {
                    checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
                }
            }
            return links.resolvedType;
        }
        function getObjectLiteralIndexInfo(propertyNodes, offset, properties, kind) {
            var propTypes = [];
            for (var i = 0; i < properties.length; i++) {
                if (kind === 0 /* String */ || isNumericName(propertyNodes[i + offset].name)) {
                    propTypes.push(getTypeOfSymbol(properties[i]));
                }
            }
            var unionType = propTypes.length ? getUnionType(propTypes, /*subtypeReduction*/ true) : undefinedType;
            return createIndexInfo(unionType, /*isReadonly*/ false);
        }
        function checkObjectLiteral(node, checkMode) {
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            // Grammar checking
            checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
            var propertiesTable = ts.createSymbolTable();
            var propertiesArray = [];
            var spread = emptyObjectType;
            var propagatedFlags = 0;
            var contextualType = getApparentTypeOfContextualType(node);
            var contextualTypeHasPattern = contextualType && contextualType.pattern &&
                (contextualType.pattern.kind === 174 /* ObjectBindingPattern */ || contextualType.pattern.kind === 178 /* ObjectLiteralExpression */);
            var isJSObjectLiteral = !contextualType && ts.isInJavaScriptFile(node);
            var typeFlags = 0;
            var patternWithComputedProperties = false;
            var hasComputedStringProperty = false;
            var hasComputedNumberProperty = false;
            var isInJSFile = ts.isInJavaScriptFile(node);
            var offset = 0;
            for (var i = 0; i < node.properties.length; i++) {
                var memberDecl = node.properties[i];
                var member = memberDecl.symbol;
                var literalName = void 0;
                if (memberDecl.kind === 261 /* PropertyAssignment */ ||
                    memberDecl.kind === 262 /* ShorthandPropertyAssignment */ ||
                    ts.isObjectLiteralMethod(memberDecl)) {
                    var jsdocType = void 0;
                    if (isInJSFile) {
                        jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl);
                    }
                    var type = void 0;
                    if (memberDecl.kind === 261 /* PropertyAssignment */) {
                        if (memberDecl.name.kind === 144 /* ComputedPropertyName */) {
                            var t = checkComputedPropertyName(memberDecl.name);
                            if (t.flags & 224 /* Literal */) {
                                literalName = ts.escapeLeadingUnderscores("" + t.value);
                            }
                        }
                        type = checkPropertyAssignment(memberDecl, checkMode);
                    }
                    else if (memberDecl.kind === 151 /* MethodDeclaration */) {
                        type = checkObjectLiteralMethod(memberDecl, checkMode);
                    }
                    else {
                        ts.Debug.assert(memberDecl.kind === 262 /* ShorthandPropertyAssignment */);
                        type = checkExpressionForMutableLocation(memberDecl.name, checkMode);
                    }
                    if (jsdocType) {
                        checkTypeAssignableTo(type, jsdocType, memberDecl);
                        type = jsdocType;
                    }
                    typeFlags |= type.flags;
                    var prop = createSymbol(4 /* Property */ | member.flags, literalName || member.escapedName);
                    if (inDestructuringPattern) {
                        // If object literal is an assignment pattern and if the assignment pattern specifies a default value
                        // for the property, make the property optional.
                        var isOptional = (memberDecl.kind === 261 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) ||
                            (memberDecl.kind === 262 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer);
                        if (isOptional) {
                            prop.flags |= 16777216 /* Optional */;
                        }
                        if (!literalName && ts.hasDynamicName(memberDecl)) {
                            patternWithComputedProperties = true;
                        }
                    }
                    else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
                        // If object literal is contextually typed by the implied type of a binding pattern, and if the
                        // binding pattern specifies a default value for the property, make the property optional.
                        var impliedProp = getPropertyOfType(contextualType, member.escapedName);
                        if (impliedProp) {
                            prop.flags |= impliedProp.flags & 16777216 /* Optional */;
                        }
                        else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, 0 /* String */)) {
                            error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType));
                        }
                    }
                    prop.declarations = member.declarations;
                    prop.parent = member.parent;
                    if (member.valueDeclaration) {
                        prop.valueDeclaration = member.valueDeclaration;
                    }
                    prop.type = type;
                    prop.target = member;
                    member = prop;
                }
                else if (memberDecl.kind === 263 /* SpreadAssignment */) {
                    if (languageVersion < 2 /* ES2015 */) {
                        checkExternalEmitHelpers(memberDecl, 2 /* Assign */);
                    }
                    if (propertiesArray.length > 0) {
                        spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
                        propertiesArray = [];
                        propertiesTable = ts.createSymbolTable();
                        hasComputedStringProperty = false;
                        hasComputedNumberProperty = false;
                        typeFlags = 0;
                    }
                    var type = checkExpression(memberDecl.expression);
                    if (!isValidSpreadType(type)) {
                        error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types);
                        return unknownType;
                    }
                    spread = getSpreadType(spread, type, node.symbol, propagatedFlags);
                    offset = i + 1;
                    continue;
                }
                else {
                    // TypeScript 1.0 spec (April 2014)
                    // A get accessor declaration is processed in the same manner as
                    // an ordinary function declaration(section 6.1) with no parameters.
                    // A set accessor declaration is processed in the same manner
                    // as an ordinary function declaration with a single parameter and a Void return type.
                    ts.Debug.assert(memberDecl.kind === 153 /* GetAccessor */ || memberDecl.kind === 154 /* SetAccessor */);
                    checkNodeDeferred(memberDecl);
                }
                if (!literalName && ts.hasDynamicName(memberDecl)) {
                    if (isNumericName(memberDecl.name)) {
                        hasComputedNumberProperty = true;
                    }
                    else {
                        hasComputedStringProperty = true;
                    }
                }
                else {
                    propertiesTable.set(member.escapedName, member);
                }
                propertiesArray.push(member);
            }
            // If object literal is contextually typed by the implied type of a binding pattern, augment the result
            // type with those properties for which the binding pattern specifies a default value.
            if (contextualTypeHasPattern) {
                for (var _i = 0, _a = getPropertiesOfType(contextualType); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (!propertiesTable.get(prop.escapedName)) {
                        if (!(prop.flags & 16777216 /* Optional */)) {
                            error(prop.valueDeclaration || prop.bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
                        }
                        propertiesTable.set(prop.escapedName, prop);
                        propertiesArray.push(prop);
                    }
                }
            }
            if (spread !== emptyObjectType) {
                if (propertiesArray.length > 0) {
                    spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
                }
                return spread;
            }
            return createObjectLiteralType();
            function createObjectLiteralType() {
                var stringIndexInfo = isJSObjectLiteral ? jsObjectLiteralIndexInfo : hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, 0 /* String */) : undefined;
                var numberIndexInfo = hasComputedNumberProperty && !isJSObjectLiteral ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, 1 /* Number */) : undefined;
                var result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshLiteral */;
                result.flags |= 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */);
                result.objectFlags |= 128 /* ObjectLiteral */;
                if (patternWithComputedProperties) {
                    result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                }
                if (inDestructuringPattern) {
                    result.pattern = node;
                }
                if (!(result.flags & 6144 /* Nullable */)) {
                    propagatedFlags |= (result.flags & 14680064 /* PropagatingFlags */);
                }
                return result;
            }
        }
        function isValidSpreadType(type) {
            return !!(type.flags & (1 /* Any */ | 16777216 /* NonPrimitive */) ||
                getFalsyFlags(type) & 7392 /* DefinitelyFalsy */ && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
                type.flags & 32768 /* Object */ && !isGenericMappedType(type) ||
                type.flags & 196608 /* UnionOrIntersection */ && !ts.forEach(type.types, function (t) { return !isValidSpreadType(t); }));
        }
        function checkJsxSelfClosingElement(node) {
            checkJsxOpeningLikeElement(node);
            return getJsxGlobalElementType() || anyType;
        }
        function checkJsxElement(node) {
            // Check attributes
            checkJsxOpeningLikeElement(node.openingElement);
            // Perform resolution on the closing tag so that rename/go to definition/etc work
            if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
                getIntrinsicTagSymbol(node.closingElement);
            }
            else {
                checkExpression(node.closingElement.tagName);
            }
            return getJsxGlobalElementType() || anyType;
        }
        /**
         * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
         */
        function isUnhyphenatedJsxName(name) {
            // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
            return !ts.stringContains(name, "-");
        }
        /**
         * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
         */
        function isJsxIntrinsicIdentifier(tagName) {
            // TODO (yuisu): comment
            switch (tagName.kind) {
                case 179 /* PropertyAccessExpression */:
                case 99 /* ThisKeyword */:
                    return false;
                case 71 /* Identifier */:
                    return ts.isIntrinsicJsxName(tagName.escapedText);
                default:
                    ts.Debug.fail();
            }
        }
        /**
         * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
         *
         * @param openingLikeElement a JSX opening-like element
         * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable
         * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
         * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
         * which also calls getSpreadType.
         */
        function createJsxAttributesTypeFromAttributesProperty(openingLikeElement, filter, checkMode) {
            var attributes = openingLikeElement.attributes;
            var attributesTable = ts.createSymbolTable();
            var spread = emptyObjectType;
            var attributesArray = [];
            var hasSpreadAnyType = false;
            var typeToIntersect;
            var explicitlySpecifyChildrenAttribute = false;
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
            for (var _i = 0, _a = attributes.properties; _i < _a.length; _i++) {
                var attributeDecl = _a[_i];
                var member = attributeDecl.symbol;
                if (ts.isJsxAttribute(attributeDecl)) {
                    var exprType = attributeDecl.initializer ?
                        checkExpression(attributeDecl.initializer, checkMode) :
                        trueType; // <Elem attr /> is sugar for <Elem attr={true} />
                    var attributeSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */ | member.flags, member.escapedName);
                    attributeSymbol.declarations = member.declarations;
                    attributeSymbol.parent = member.parent;
                    if (member.valueDeclaration) {
                        attributeSymbol.valueDeclaration = member.valueDeclaration;
                    }
                    attributeSymbol.type = exprType;
                    attributeSymbol.target = member;
                    attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
                    attributesArray.push(attributeSymbol);
                    if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
                        explicitlySpecifyChildrenAttribute = true;
                    }
                }
                else {
                    ts.Debug.assert(attributeDecl.kind === 255 /* JsxSpreadAttribute */);
                    if (attributesArray.length > 0) {
                        spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0);
                        attributesArray = [];
                        attributesTable = ts.createSymbolTable();
                    }
                    var exprType = checkExpression(attributeDecl.expression);
                    if (isTypeAny(exprType)) {
                        hasSpreadAnyType = true;
                    }
                    if (isValidSpreadType(exprType)) {
                        spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*propagatedFlags*/ 0);
                    }
                    else {
                        typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
                    }
                }
            }
            if (!hasSpreadAnyType) {
                if (spread !== emptyObjectType) {
                    if (attributesArray.length > 0) {
                        spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0);
                    }
                    attributesArray = getPropertiesOfType(spread);
                }
                attributesTable = ts.createSymbolTable();
                for (var _b = 0, attributesArray_1 = attributesArray; _b < attributesArray_1.length; _b++) {
                    var attr = attributesArray_1[_b];
                    if (!filter || filter(attr)) {
                        attributesTable.set(attr.escapedName, attr);
                    }
                }
            }
            // Handle children attribute
            var parent = openingLikeElement.parent.kind === 249 /* JsxElement */ ? openingLikeElement.parent : undefined;
            // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement
            if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) {
                var childrenTypes = [];
                for (var _c = 0, _d = parent.children; _c < _d.length; _c++) {
                    var child = _d[_c];
                    // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
                    // because then type of children property will have constituent of string type.
                    if (child.kind === 10 /* JsxText */) {
                        if (!child.containsOnlyWhiteSpaces) {
                            childrenTypes.push(stringType);
                        }
                    }
                    else {
                        childrenTypes.push(checkExpression(child, checkMode));
                    }
                }
                if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
                    // Error if there is a attribute named "children" explicitly specified and children element.
                    // This is because children element will overwrite the value from attributes.
                    // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread.
                    if (explicitlySpecifyChildrenAttribute) {
                        error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName));
                    }
                    // If there are children in the body of JSX element, create dummy attribute "children" with anyType so that it will pass the attribute checking process
                    var childrenPropSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */, jsxChildrenPropertyName);
                    childrenPropSymbol.type = childrenTypes.length === 1 ?
                        childrenTypes[0] :
                        createArrayType(getUnionType(childrenTypes, /*subtypeReduction*/ false));
                    attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol);
                }
            }
            if (hasSpreadAnyType) {
                return anyType;
            }
            var attributeType = createJsxAttributesType(attributes.symbol, attributesTable);
            return typeToIntersect && attributesTable.size ? getIntersectionType([typeToIntersect, attributeType]) :
                typeToIntersect ? typeToIntersect : attributeType;
            /**
             * Create anonymous type from given attributes symbol table.
             * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable
             * @param attributesTable a symbol table of attributes property
             */
            function createJsxAttributesType(symbol, attributesTable) {
                var result = createAnonymousType(symbol, attributesTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                result.flags |= 33554432 /* JsxAttributes */ | 4194304 /* ContainsObjectLiteral */;
                result.objectFlags |= 128 /* ObjectLiteral */;
                return result;
            }
        }
        /**
         * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
         * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
         * @param node a JSXAttributes to be resolved of its type
         */
        function checkJsxAttributes(node, checkMode) {
            return createJsxAttributesTypeFromAttributesProperty(node.parent, /*filter*/ undefined, checkMode);
        }
        function getJsxType(name) {
            var jsxType = jsxTypes.get(name);
            if (jsxType === undefined) {
                jsxTypes.set(name, jsxType = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType);
            }
            return jsxType;
        }
        /**
         * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
         * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
         * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement).
         * May also return unknownSymbol if both of these lookups fail.
         */
        function getIntrinsicTagSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
                if (intrinsicElementsType !== unknownType) {
                    // Property case
                    if (!ts.isIdentifier(node.tagName))
                        throw ts.Debug.fail();
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText);
                    if (intrinsicProp) {
                        links.jsxFlags |= 1 /* IntrinsicNamedElement */;
                        return links.resolvedSymbol = intrinsicProp;
                    }
                    // Intrinsic string indexer case
                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                    if (indexSignatureType) {
                        links.jsxFlags |= 2 /* IntrinsicIndexedElement */;
                        return links.resolvedSymbol = intrinsicElementsType.symbol;
                    }
                    // Wasn't found
                    error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements);
                    return links.resolvedSymbol = unknownSymbol;
                }
                else {
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements));
                    }
                    return links.resolvedSymbol = unknownSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        /**
         * Given a JSX element that is a class element, finds the Element Instance Type. If the
         * element is not a class element, or the class element type cannot be determined, returns 'undefined'.
         * For example, in the element <MyClass>, the element instance type is `MyClass` (not `typeof MyClass`).
         */
        function getJsxElementInstanceType(node, valueType) {
            ts.Debug.assert(!(valueType.flags & 65536 /* Union */));
            if (isTypeAny(valueType)) {
                // Short-circuit if the class tag is using an element type 'any'
                return anyType;
            }
            // Resolve the signatures, preferring constructor
            var signatures = getSignaturesOfType(valueType, 1 /* Construct */);
            if (signatures.length === 0) {
                // No construct signatures, try call signatures
                signatures = getSignaturesOfType(valueType, 0 /* Call */);
                if (signatures.length === 0) {
                    // We found no signatures at all, which is an error
                    error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName));
                    return unknownType;
                }
            }
            var instantiatedSignatures = [];
            for (var _i = 0, signatures_3 = signatures; _i < signatures_3.length; _i++) {
                var signature = signatures_3[_i];
                if (signature.typeParameters) {
                    var isJavascript = ts.isInJavaScriptFile(node);
                    var typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0, isJavascript);
                    instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
                }
                else {
                    instantiatedSignatures.push(signature);
                }
            }
            return getUnionType(ts.map(instantiatedSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
        }
        /**
         * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer.
         * Get a single property from that container if existed. Report an error if there are more than one property.
         *
         * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer
         *          if other string is given or the container doesn't exist, return undefined.
         */
        function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer) {
            // JSX
            var jsxNamespace = getGlobalSymbol(JsxNames.JSX, 1920 /* Namespace */, /*diagnosticMessage*/ undefined);
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
            var jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, 793064 /* Type */);
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
            var jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
            // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute
            var propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
            if (propertiesOfJsxElementAttribPropInterface) {
                // Element Attributes has zero properties, so the element attributes type will be the class instance type
                if (propertiesOfJsxElementAttribPropInterface.length === 0) {
                    return "";
                }
                else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
                    return propertiesOfJsxElementAttribPropInterface[0].escapedName;
                }
                else if (propertiesOfJsxElementAttribPropInterface.length > 1) {
                    // More than one property on ElementAttributesProperty is an error
                    error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer));
                }
            }
            return undefined;
        }
        /// e.g. "props" for React.d.ts,
        /// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
        ///     non-intrinsic elements' attributes type is 'any'),
        /// or '' if it has 0 properties (which means every
        ///     non-intrinsic elements' attributes type is the element instance type)
        function getJsxElementPropertiesName() {
            if (!_hasComputedJsxElementPropertiesName) {
                _hasComputedJsxElementPropertiesName = true;
                _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer);
            }
            return _jsxElementPropertiesName;
        }
        function getJsxElementChildrenPropertyname() {
            if (!_hasComputedJsxElementChildrenPropertyName) {
                _hasComputedJsxElementChildrenPropertyName = true;
                _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer);
            }
            return _jsxElementChildrenPropertyName;
        }
        function getApparentTypeOfJsxPropsType(propsType) {
            if (!propsType) {
                return undefined;
            }
            if (propsType.flags & 131072 /* Intersection */) {
                var propsApparentType = [];
                for (var _i = 0, _a = propsType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    propsApparentType.push(getApparentType(t));
                }
                return getIntersectionType(propsApparentType);
            }
            return getApparentType(propsType);
        }
        /**
         * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component.
         * Return only attributes type of successfully resolved call signature.
         * This function assumes that the caller handled other possible element type of the JSX element (e.g. stateful component)
         * Unlike tryGetAllJsxStatelessFunctionAttributesType, this function is a default behavior of type-checkers.
         * @param openingLikeElement a JSX opening-like element to find attributes type
         * @param elementType a type of the opening-like element. This elementType can't be an union type
         * @param elemInstanceType an element instance type (the result of newing or invoking this tag)
         * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global
         */
        function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) {
            ts.Debug.assert(!(elementType.flags & 65536 /* Union */));
            if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
                var jsxStatelessElementType = getJsxGlobalStatelessElementType();
                if (jsxStatelessElementType) {
                    // We don't call getResolvedSignature here because we have already resolve the type of JSX Element.
                    var callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined);
                    if (callSignature !== unknownSignature) {
                        var callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
                        var paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
                        paramType = getApparentTypeOfJsxPropsType(paramType);
                        if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
                            // Intersect in JSX.IntrinsicAttributes if it exists
                            var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
                            if (intrinsicAttributes !== unknownType) {
                                paramType = intersectTypes(intrinsicAttributes, paramType);
                            }
                            return paramType;
                        }
                    }
                }
            }
            return undefined;
        }
        /**
         * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component.
         * Return all attributes type of resolved call signature including candidate signatures.
         * This function assumes that the caller handled other possible element type of the JSX element.
         * This function is a behavior used by language service when looking up completion in JSX element.
         * @param openingLikeElement a JSX opening-like element to find attributes type
         * @param elementType a type of the opening-like element. This elementType can't be an union type
         * @param elemInstanceType an element instance type (the result of newing or invoking this tag)
         * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global
         */
        function tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) {
            ts.Debug.assert(!(elementType.flags & 65536 /* Union */));
            if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
                // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type
                var jsxStatelessElementType = getJsxGlobalStatelessElementType();
                if (jsxStatelessElementType) {
                    // We don't call getResolvedSignature because here we have already resolve the type of JSX Element.
                    var candidatesOutArray = [];
                    getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray);
                    var result = void 0;
                    var allMatchingAttributesType = void 0;
                    for (var _i = 0, candidatesOutArray_1 = candidatesOutArray; _i < candidatesOutArray_1.length; _i++) {
                        var candidate = candidatesOutArray_1[_i];
                        var callReturnType = getReturnTypeOfSignature(candidate);
                        var paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0]));
                        paramType = getApparentTypeOfJsxPropsType(paramType);
                        if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
                            var shouldBeCandidate = true;
                            for (var _a = 0, _b = openingLikeElement.attributes.properties; _a < _b.length; _a++) {
                                var attribute = _b[_a];
                                if (ts.isJsxAttribute(attribute) &&
                                    isUnhyphenatedJsxName(attribute.name.escapedText) &&
                                    !getPropertyOfType(paramType, attribute.name.escapedText)) {
                                    shouldBeCandidate = false;
                                    break;
                                }
                            }
                            if (shouldBeCandidate) {
                                result = intersectTypes(result, paramType);
                            }
                            allMatchingAttributesType = intersectTypes(allMatchingAttributesType, paramType);
                        }
                    }
                    // If we can't find any matching, just return everything.
                    if (!result) {
                        result = allMatchingAttributesType;
                    }
                    // Intersect in JSX.IntrinsicAttributes if it exists
                    var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
                    if (intrinsicAttributes !== unknownType) {
                        result = intersectTypes(intrinsicAttributes, result);
                    }
                    return result;
                }
            }
            return undefined;
        }
        /**
         * Resolve attributes type of the given opening-like element. The attributes type is a type of attributes associated with the given elementType.
         * For instance:
         *      declare function Foo(attr: { p1: string}): JSX.Element;
         *      <Foo p1={10} />;  // This function will try resolve "Foo" and return an attributes type of "Foo" which is "{ p1: string }"
         *
         * The function is intended to initially be called from getAttributesTypeFromJsxOpeningLikeElement which already handle JSX-intrinsic-element..
         * This function will try to resolve custom JSX attributes type in following order: string literal, stateless function, and stateful component
         *
         * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement
         * @param shouldIncludeAllStatelessAttributesType a boolean indicating whether to include all attributes types from all stateless function signature
         * @param elementType an instance type of the given opening-like element. If undefined, the function will check type openinglikeElement's tagname.
         * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts)
         * @return attributes type if able to resolve the type of node
         *         anyType if there is no type ElementAttributesProperty or there is an error
         *         emptyObjectType if there is no "prop" in the element instance type
         */
        function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) {
            if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); }
            if (elementType.flags & 65536 /* Union */) {
                var types = elementType.types;
                return getUnionType(types.map(function (type) {
                    return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType);
                }), /*subtypeReduction*/ true);
            }
            // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type
            if (elementType.flags & 2 /* String */) {
                return anyType;
            }
            else if (elementType.flags & 32 /* StringLiteral */) {
                // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type
                // For example:
                //      var CustomTag: "h1" = "h1";
                //      <CustomTag> Hello World </CustomTag>
                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
                if (intrinsicElementsType !== unknownType) {
                    var stringLiteralTypeName = elementType.value;
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName));
                    if (intrinsicProp) {
                        return getTypeOfSymbol(intrinsicProp);
                    }
                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                    if (indexSignatureType) {
                        return indexSignatureType;
                    }
                    error(openingLikeElement, ts.Diagnostics.Property_0_does_not_exist_on_type_1, stringLiteralTypeName, "JSX." + JsxNames.IntrinsicElements);
                }
                // If we need to report an error, we already done so here. So just return any to prevent any more error downstream
                return anyType;
            }
            // Get the element instance type (the result of newing or invoking this tag)
            var elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType);
            // If we should include all stateless attributes type, then get all attributes type from all stateless function signature.
            // Otherwise get only attributes type from the signature picked by choose-overload logic.
            var statelessAttributesType = shouldIncludeAllStatelessAttributesType ?
                tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) :
                defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType);
            if (statelessAttributesType) {
                return statelessAttributesType;
            }
            // Issue an error if this return type isn't assignable to JSX.ElementClass
            if (elementClassType) {
                checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, ts.Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
            }
            if (isTypeAny(elemInstanceType)) {
                return elemInstanceType;
            }
            var propsName = getJsxElementPropertiesName();
            if (propsName === undefined) {
                // There is no type ElementAttributesProperty, return 'any'
                return anyType;
            }
            else if (propsName === "") {
                // If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
                return elemInstanceType;
            }
            else {
                var attributesType = getTypeOfPropertyOfType(elemInstanceType, propsName);
                if (!attributesType) {
                    // There is no property named 'props' on this instance type
                    return emptyObjectType;
                }
                else if (isTypeAny(attributesType) || (attributesType === unknownType)) {
                    // Props is of type 'any' or unknown
                    return attributesType;
                }
                else {
                    // Normal case -- add in IntrinsicClassElements<T> and IntrinsicElements
                    var apparentAttributesType = attributesType;
                    var intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes);
                    if (intrinsicClassAttribs !== unknownType) {
                        var typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol);
                        if (typeParams) {
                            if (typeParams.length === 1) {
                                apparentAttributesType = intersectTypes(createTypeReference(intrinsicClassAttribs, [elemInstanceType]), apparentAttributesType);
                            }
                        }
                        else {
                            apparentAttributesType = intersectTypes(attributesType, intrinsicClassAttribs);
                        }
                    }
                    var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes);
                    if (intrinsicAttribs !== unknownType) {
                        apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType);
                    }
                    return apparentAttributesType;
                }
            }
        }
        /**
         * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name.
         * The function is intended to be called from a function which has checked that the opening element is an intrinsic element.
         * @param node an intrinsic JSX opening-like element
         */
        function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node) {
            ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName));
            var links = getNodeLinks(node);
            if (!links.resolvedJsxElementAttributesType) {
                var symbol = getIntrinsicTagSymbol(node);
                if (links.jsxFlags & 1 /* IntrinsicNamedElement */) {
                    return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol);
                }
                else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) {
                    return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, 0 /* String */).type;
                }
                else {
                    return links.resolvedJsxElementAttributesType = unknownType;
                }
            }
            return links.resolvedJsxElementAttributesType;
        }
        /**
         * Get attributes type of the given custom opening-like JSX element.
         * This function is intended to be called from a caller that handles intrinsic JSX element already.
         * @param node a custom JSX opening-like element
         * @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component
         */
        function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) {
            var links = getNodeLinks(node);
            var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType";
            if (!links[linkLocation]) {
                var elemClassType = getJsxGlobalElementClassType();
                return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType);
            }
            return links[linkLocation];
        }
        /**
         * Get all possible attributes type, especially from an overload stateless function component, of the given JSX opening-like element.
         * This function is called by language service (see: completions-tryGetGlobalSymbols).
         * @param node a JSX opening-like element to get attributes type for
         */
        function getAllAttributesTypeFromJsxOpeningLikeElement(node) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
            }
            else {
                // Because in language service, the given JSX opening-like element may be incomplete and therefore,
                // we can't resolve to exact signature if the element is a stateless function component so the best thing to do is return all attributes type from all overloads.
                return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true);
            }
        }
        /**
         * Get the attributes type, which indicates the attributes that are valid on the given JSXOpeningLikeElement.
         * @param node a JSXOpeningLikeElement node
         * @return an attributes type of the given node
         */
        function getAttributesTypeFromJsxOpeningLikeElement(node) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
            }
            else {
                return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ false);
            }
        }
        /**
         * Given a JSX attribute, returns the symbol for the corresponds property
         * of the element attributes type. Will return unknownSymbol for attributes
         * that have no matching element attributes type property.
         */
        function getJsxAttributePropertySymbol(attrib) {
            var attributesType = getAttributesTypeFromJsxOpeningLikeElement(attrib.parent.parent);
            var prop = getPropertyOfType(attributesType, attrib.name.escapedText);
            return prop || unknownSymbol;
        }
        function getJsxGlobalElementClassType() {
            if (!deferredJsxElementClassType) {
                deferredJsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
            }
            return deferredJsxElementClassType;
        }
        function getJsxGlobalElementType() {
            if (!deferredJsxElementType) {
                deferredJsxElementType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.Element);
            }
            return deferredJsxElementType;
        }
        function getJsxGlobalStatelessElementType() {
            if (!deferredJsxStatelessElementType) {
                var jsxElementType = getJsxGlobalElementType();
                if (jsxElementType) {
                    deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]);
                }
            }
            return deferredJsxStatelessElementType;
        }
        /**
         * Returns all the properties of the Jsx.IntrinsicElements interface
         */
        function getJsxIntrinsicTagNames() {
            var intrinsics = getJsxType(JsxNames.IntrinsicElements);
            return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray;
        }
        function checkJsxPreconditions(errorNode) {
            // Preconditions for using JSX
            if ((compilerOptions.jsx || 0 /* None */) === 0 /* None */) {
                error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
            }
            if (getJsxGlobalElementType() === undefined) {
                if (noImplicitAny) {
                    error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
                }
            }
        }
        function checkJsxOpeningLikeElement(node) {
            checkGrammarJsxElement(node);
            checkJsxPreconditions(node);
            // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
            // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
            var reactRefErr = diagnostics && compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined;
            var reactNamespace = getJsxNamespace();
            var reactSym = resolveName(node.tagName, reactNamespace, 107455 /* Value */, reactRefErr, reactNamespace, /*isUse*/ true);
            if (reactSym) {
                // Mark local symbol as referenced here because it might not have been marked
                // if jsx emit was not react as there wont be error being emitted
                reactSym.isReferenced = true;
                // If react symbol is alias, mark it as refereced
                if (reactSym.flags & 2097152 /* Alias */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) {
                    markAliasSymbolAsReferenced(reactSym);
                }
            }
            checkJsxAttributesAssignableToTagNameAttributes(node);
        }
        /**
         * Check if a property with the given name is known anywhere in the given type. In an object type, a property
         * is considered known if
         * 1. the object type is empty and the check is for assignability, or
         * 2. if the object type has index signatures, or
         * 3. if the property is actually declared in the object type
         *    (this means that 'toString', for example, is not usually a known property).
         * 4. In a union or intersection type,
         *    a property is considered known if it is known in any constituent type.
         * @param targetType a type to search a given name in
         * @param name a property name to search
         * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
         */
        function isKnownProperty(targetType, name, isComparingJsxAttributes) {
            if (targetType.flags & 32768 /* Object */) {
                var resolved = resolveStructuredTypeMembers(targetType);
                if (resolved.stringIndexInfo ||
                    resolved.numberIndexInfo && isNumericLiteralName(name) ||
                    getPropertyOfObjectType(targetType, name) ||
                    isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
                    // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
                    return true;
                }
            }
            else if (targetType.flags & 196608 /* UnionOrIntersection */) {
                for (var _i = 0, _a = targetType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isKnownProperty(t, name, isComparingJsxAttributes)) {
                        return true;
                    }
                }
            }
            return false;
        }
        /**
         * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes.
         *      Get the attributes type of the opening-like element through resolving the tagName, "target attributes"
         *      Check assignablity between given attributes property, "source attributes", and the "target attributes"
         * @param openingLikeElement an opening-like JSX element to check its JSXAttributes
         */
        function checkJsxAttributesAssignableToTagNameAttributes(openingLikeElement) {
            // The function involves following steps:
            //      1. Figure out expected attributes type by resolving tagName of the JSX opening-like element, targetAttributesType.
            //         During these steps, we will try to resolve the tagName as intrinsic name, stateless function, stateful component (in the order)
            //      2. Solved JSX attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element.
            //      3. Check if the two are assignable to each other
            // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element.
            var targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ?
                getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) :
                getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false);
            // sourceAttributesType is a type of an attributes properties.
            // i.e <div attr1={10} attr2="string" />
            //     attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes".
            var sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, function (attribute) {
                return isUnhyphenatedJsxName(attribute.escapedName) || !!(getPropertyOfType(targetAttributesType, attribute.escapedName));
            });
            // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type.
            // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass.
            if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || sourceAttributesType.properties.length > 0)) {
                error(openingLikeElement, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(getJsxElementPropertiesName()));
            }
            else {
                // Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties
                var isSourceAttributeTypeAssignableToTarget = checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement);
                // After we check for assignability, we will do another pass to check that all explicitly specified attributes have correct name corresponding in targetAttributeType.
                // This will allow excess properties in spread type as it is very common pattern to spread outter attributes into React component in its render method.
                if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) {
                    for (var _i = 0, _a = openingLikeElement.attributes.properties; _i < _a.length; _i++) {
                        var attribute = _a[_i];
                        if (ts.isJsxAttribute(attribute) && !isKnownProperty(targetAttributesType, attribute.name.escapedText, /*isComparingJsxAttributes*/ true)) {
                            error(attribute, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(attribute.name), typeToString(targetAttributesType));
                            // We break here so that errors won't be cascading
                            break;
                        }
                    }
                }
            }
        }
        function checkJsxExpression(node, checkMode) {
            if (node.expression) {
                var type = checkExpression(node.expression, checkMode);
                if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
                    error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type);
                }
                return type;
            }
            else {
                return unknownType;
            }
        }
        // If a symbol is a synthesized symbol with no value declaration, we assume it is a property. Example of this are the synthesized
        // '.prototype' property as well as synthesized tuple index properties.
        function getDeclarationKindFromSymbol(s) {
            return s.valueDeclaration ? s.valueDeclaration.kind : 149 /* PropertyDeclaration */;
        }
        function getDeclarationNodeFlagsFromSymbol(s) {
            return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0;
        }
        function isMethodLike(symbol) {
            return !!(symbol.flags & 8192 /* Method */ || ts.getCheckFlags(symbol) & 4 /* SyntheticMethod */);
        }
        /**
         * Check whether the requested property access is valid.
         * Returns true if node is a valid property access, and false otherwise.
         * @param node The node to be checked.
         * @param left The left hand side of the property access (e.g.: the super in `super.foo`).
         * @param type The type of left.
         * @param prop The symbol for the right hand side of the property access.
         */
        function checkPropertyAccessibility(node, left, type, prop) {
            var flags = ts.getDeclarationModifierFlagsFromSymbol(prop);
            var errorNode = node.kind === 179 /* PropertyAccessExpression */ || node.kind === 226 /* VariableDeclaration */ ?
                node.name :
                node.right;
            if (ts.getCheckFlags(prop) & 256 /* ContainsPrivate */) {
                // Synthetic property with private constituent property
                error(errorNode, ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(prop), typeToString(type));
                return false;
            }
            if (left.kind === 97 /* SuperKeyword */) {
                // TS 1.0 spec (April 2014): 4.8.2
                // - In a constructor, instance member function, instance member accessor, or
                //   instance member variable initializer where this references a derived class instance,
                //   a super property access is permitted and must specify a public instance member function of the base class.
                // - In a static member function or static member accessor
                //   where this references the constructor function object of a derived class,
                //   a super property access is permitted and must specify a public static member function of the base class.
                if (languageVersion < 2 /* ES2015 */) {
                    var hasNonMethodDeclaration = forEachProperty(prop, function (p) {
                        var propKind = getDeclarationKindFromSymbol(p);
                        return propKind !== 151 /* MethodDeclaration */ && propKind !== 150 /* MethodSignature */;
                    });
                    if (hasNonMethodDeclaration) {
                        error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                        return false;
                    }
                }
                if (flags & 128 /* Abstract */) {
                    // A method cannot be accessed in a super property access if the method is abstract.
                    // This error could mask a private property access error. But, a member
                    // cannot simultaneously be private and abstract, so this will trigger an
                    // additional error elsewhere.
                    error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
            }
            // Public properties are otherwise accessible.
            if (!(flags & 24 /* NonPublicAccessibilityModifier */)) {
                return true;
            }
            // Property is known to be private or protected at this point
            // Private property is accessible if the property is within the declaring class
            if (flags & 8 /* Private */) {
                var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                    error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
                return true;
            }
            // Property is known to be protected at this point
            // All protected properties of a supertype are accessible in a super access
            if (left.kind === 97 /* SuperKeyword */) {
                return true;
            }
            // Find the first enclosing class that has the declaring classes of the protected constituents
            // of the property as base classes
            var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
                var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
                return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
            });
            // A protected property is accessible if the property is within the declaring class or classes derived from it
            if (!enclosingClass) {
                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || type));
                return false;
            }
            // No further restrictions for static properties
            if (flags & 32 /* Static */) {
                return true;
            }
            // An instance property must be accessed through an instance of the enclosing class
            if (type.flags & 16384 /* TypeParameter */ && type.isThisType) {
                // get the original type -- represented as the type constraint of the 'this' type
                type = getConstraintOfTypeParameter(type);
            }
            if (!(getObjectFlags(getTargetType(type)) & 3 /* ClassOrInterface */ && hasBaseType(type, enclosingClass))) {
                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                return false;
            }
            return true;
        }
        function checkNonNullExpression(node) {
            return checkNonNullType(checkExpression(node), node);
        }
        function checkNonNullType(type, errorNode) {
            var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 6144 /* Nullable */;
            if (kind) {
                error(errorNode, kind & 2048 /* Undefined */ ? kind & 4096 /* Null */ ?
                    ts.Diagnostics.Object_is_possibly_null_or_undefined :
                    ts.Diagnostics.Object_is_possibly_undefined :
                    ts.Diagnostics.Object_is_possibly_null);
                var t = getNonNullableType(type);
                return t.flags & (6144 /* Nullable */ | 8192 /* Never */) ? unknownType : t;
            }
            return type;
        }
        function checkPropertyAccessExpression(node) {
            return checkPropertyAccessExpressionOrQualifiedName(node, node.expression, node.name);
        }
        function checkQualifiedName(node) {
            return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right);
        }
        function checkPropertyAccessExpressionOrQualifiedName(node, left, right) {
            var type = checkNonNullExpression(left);
            if (isTypeAny(type) || type === silentNeverType) {
                return type;
            }
            var apparentType = getApparentType(getWidenedType(type));
            if (apparentType === unknownType || (type.flags & 16384 /* TypeParameter */ && isTypeAny(apparentType))) {
                // handle cases when type is Type parameter with invalid or any constraint
                return apparentType;
            }
            var prop = getPropertyOfType(apparentType, right.escapedText);
            if (!prop) {
                var indexInfo = getIndexInfoOfType(apparentType, 0 /* String */);
                if (indexInfo && indexInfo.type) {
                    if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) {
                        error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
                    }
                    return indexInfo.type;
                }
                if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
                    reportNonexistentProperty(right, type.flags & 16384 /* TypeParameter */ && type.isThisType ? apparentType : type);
                }
                return unknownType;
            }
            checkPropertyNotUsedBeforeDeclaration(prop, node, right);
            markPropertyAsReferenced(prop, node, left.kind === 99 /* ThisKeyword */);
            getNodeLinks(node).resolvedSymbol = prop;
            checkPropertyAccessibility(node, left, apparentType, prop);
            var propType = getDeclaredOrApparentType(prop, node);
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (assignmentKind) {
                if (isReferenceToReadonlyEntity(node, prop) || isReferenceThroughNamespaceImport(node)) {
                    error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, ts.idText(right));
                    return unknownType;
                }
            }
            // Only compute control flow type if this is a property access expression that isn't an
            // assignment target, and the referenced property was declared as a variable, property,
            // accessor, or optional method.
            if (node.kind !== 179 /* PropertyAccessExpression */ || assignmentKind === 1 /* Definite */ ||
                !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) &&
                    !(prop.flags & 8192 /* Method */ && propType.flags & 65536 /* Union */)) {
                return propType;
            }
            var flowType = getFlowTypeOfReference(node, propType);
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function checkPropertyNotUsedBeforeDeclaration(prop, node, right) {
            var valueDeclaration = prop.valueDeclaration;
            if (!valueDeclaration) {
                return;
            }
            if (isInPropertyInitializer(node) &&
                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
                && !isPropertyDeclaredInAncestorClass(prop)) {
                error(right, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.idText(right));
            }
            else if (valueDeclaration.kind === 229 /* ClassDeclaration */ &&
                node.parent.kind !== 159 /* TypeReference */ &&
                !ts.isInAmbientContext(valueDeclaration) &&
                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
                error(right, ts.Diagnostics.Class_0_used_before_its_declaration, ts.idText(right));
            }
        }
        function isInPropertyInitializer(node) {
            return !!ts.findAncestor(node, function (node) {
                switch (node.kind) {
                    case 149 /* PropertyDeclaration */:
                        return true;
                    case 261 /* PropertyAssignment */:
                        // We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`.
                        return false;
                    default:
                        return ts.isPartOfExpression(node) ? false : "quit";
                }
            });
        }
        /**
         * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass.
         * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration.
         */
        function isPropertyDeclaredInAncestorClass(prop) {
            var classType = getTypeOfSymbol(prop.parent);
            while (true) {
                classType = getSuperClass(classType);
                if (!classType) {
                    return false;
                }
                var superProperty = getPropertyOfObjectType(classType, prop.escapedName);
                if (superProperty && superProperty.valueDeclaration) {
                    return true;
                }
            }
        }
        function getSuperClass(classType) {
            var x = getBaseTypes(classType);
            if (x.length === 0) {
                return undefined;
            }
            ts.Debug.assert(x.length === 1);
            return x[0];
        }
        function reportNonexistentProperty(propNode, containingType) {
            var errorInfo;
            if (containingType.flags & 65536 /* Union */ && !(containingType.flags & 8190 /* Primitive */)) {
                for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                    var subtype = _a[_i];
                    if (!getPropertyOfType(subtype, propNode.escapedText)) {
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype));
                        break;
                    }
                }
            }
            var suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
            if (suggestion !== undefined) {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, ts.declarationNameToString(propNode), typeToString(containingType), suggestion);
            }
            else {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
            }
            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo));
        }
        function getSuggestionForNonexistentProperty(node, containingType) {
            var suggestion = getSpellingSuggestionForName(ts.idText(node), getPropertiesOfType(containingType), 107455 /* Value */);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestionForNonexistentSymbol(location, name, meaning) {
            var result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, function (symbols, name, meaning) {
                // `name` from the callback === the outer `name`
                var symbol = getSymbol(symbols, name, meaning);
                // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
                // So the table *contains* `x` but `x` isn't actually in scope.
                // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
                return symbol || getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), ts.arrayFrom(symbols.values()), meaning);
            });
            return result && ts.symbolName(result);
        }
        /**
         * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
         * Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
         *
         * If there is a candidate that's the same except for case, return that.
         * If there is a candidate that's within one edit of the name, return that.
         * Otherwise, return the candidate with the smallest Levenshtein distance,
         *    except for candidates:
         *      * With no name
         *      * Whose meaning doesn't match the `meaning` parameter.
         *      * Whose length differs from the target name by more than 0.3 of the length of the name.
         *      * Whose levenshtein distance is more than 0.4 of the length of the name
         *        (0.4 allows 1 substitution/transposition for every 5 characters,
         *         and 1 insertion/deletion at 3 characters)
         * Names longer than 30 characters don't get suggestions because Levenshtein distance is an n**2 algorithm.
         */
        function getSpellingSuggestionForName(name, symbols, meaning) {
            var worstDistance = name.length * 0.4;
            var maximumLengthDifference = Math.min(3, name.length * 0.34);
            var bestDistance = Number.MAX_VALUE;
            var bestCandidate = undefined;
            var justCheckExactMatches = false;
            if (name.length > 30) {
                return undefined;
            }
            name = name.toLowerCase();
            for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
                var candidate = symbols_3[_i];
                var candidateName = ts.symbolName(candidate);
                if (candidate.flags & meaning &&
                    candidateName &&
                    Math.abs(candidateName.length - name.length) < maximumLengthDifference) {
                    candidateName = candidateName.toLowerCase();
                    if (candidateName === name) {
                        return candidate;
                    }
                    if (justCheckExactMatches) {
                        continue;
                    }
                    if (candidateName.length < 3 ||
                        name.length < 3 ||
                        candidateName === "eval" ||
                        candidateName === "intl" ||
                        candidateName === "undefined" ||
                        candidateName === "map" ||
                        candidateName === "nan" ||
                        candidateName === "set") {
                        continue;
                    }
                    var distance = ts.levenshtein(name, candidateName);
                    if (distance > worstDistance) {
                        continue;
                    }
                    if (distance < 3) {
                        justCheckExactMatches = true;
                        bestCandidate = candidate;
                    }
                    else if (distance < bestDistance) {
                        bestDistance = distance;
                        bestCandidate = candidate;
                    }
                }
            }
            return bestCandidate;
        }
        function markPropertyAsReferenced(prop, nodeForCheckWriteOnly, isThisAccess) {
            if (prop &&
                noUnusedIdentifiers &&
                (prop.flags & 106500 /* ClassMember */) &&
                prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8 /* Private */)
                && !(nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly))) {
                if (isThisAccess) {
                    // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters).
                    var containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration);
                    if (containingMethod && containingMethod.symbol === prop) {
                        return;
                    }
                }
                if (ts.getCheckFlags(prop) & 1 /* Instantiated */) {
                    getSymbolLinks(prop).target.isReferenced = true;
                }
                else {
                    prop.isReferenced = true;
                }
            }
        }
        function isValidPropertyAccess(node, propertyName) {
            var left = node.kind === 179 /* PropertyAccessExpression */
                ? node.expression
                : node.left;
            return isValidPropertyAccessWithType(node, left, propertyName, getWidenedType(checkExpression(left)));
        }
        function isValidPropertyAccessWithType(node, left, propertyName, type) {
            if (type !== unknownType && !isTypeAny(type)) {
                var prop = getPropertyOfType(type, propertyName);
                if (prop) {
                    return checkPropertyAccessibility(node, left, type, prop);
                }
                // In js files properties of unions are allowed in completion
                if (ts.isInJavaScriptFile(left) && (type.flags & 65536 /* Union */)) {
                    for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                        var elementType = _a[_i];
                        if (isValidPropertyAccessWithType(node, left, propertyName, elementType)) {
                            return true;
                        }
                    }
                }
                return false;
            }
            return true;
        }
        /**
         * Return the symbol of the for-in variable declared or referenced by the given for-in statement.
         */
        function getForInVariableSymbol(node) {
            var initializer = node.initializer;
            if (initializer.kind === 227 /* VariableDeclarationList */) {
                var variable = initializer.declarations[0];
                if (variable && !ts.isBindingPattern(variable.name)) {
                    return getSymbolOfNode(variable);
                }
            }
            else if (initializer.kind === 71 /* Identifier */) {
                return getResolvedSymbol(initializer);
            }
            return undefined;
        }
        /**
         * Return true if the given type is considered to have numeric property names.
         */
        function hasNumericPropertyNames(type) {
            return getIndexTypeOfType(type, 1 /* Number */) && !getIndexTypeOfType(type, 0 /* String */);
        }
        /**
         * Return true if given node is an expression consisting of an identifier (possibly parenthesized)
         * that references a for-in variable for an object with numeric property names.
         */
        function isForInVariableForNumericPropertyNames(expr) {
            var e = ts.skipParentheses(expr);
            if (e.kind === 71 /* Identifier */) {
                var symbol = getResolvedSymbol(e);
                if (symbol.flags & 3 /* Variable */) {
                    var child = expr;
                    var node = expr.parent;
                    while (node) {
                        if (node.kind === 215 /* ForInStatement */ &&
                            child === node.statement &&
                            getForInVariableSymbol(node) === symbol &&
                            hasNumericPropertyNames(getTypeOfExpression(node.expression))) {
                            return true;
                        }
                        child = node;
                        node = node.parent;
                    }
                }
            }
            return false;
        }
        function checkIndexedAccess(node) {
            var objectType = checkNonNullExpression(node.expression);
            var indexExpression = node.argumentExpression;
            if (!indexExpression) {
                var sourceFile = ts.getSourceFileOfNode(node);
                if (node.parent.kind === 182 /* NewExpression */ && node.parent.expression === node) {
                    var start = ts.skipTrivia(sourceFile.text, node.expression.end);
                    var end = node.end;
                    grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead);
                }
                else {
                    var start = node.end - "]".length;
                    var end = node.end;
                    grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Expression_expected);
                }
                return unknownType;
            }
            var indexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : checkExpression(indexExpression);
            if (objectType === unknownType || objectType === silentNeverType) {
                return objectType;
            }
            if (isConstEnumObjectType(objectType) && indexExpression.kind !== 9 /* StringLiteral */) {
                error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
                return unknownType;
            }
            return checkIndexedAccessIndexType(getIndexedAccessType(objectType, indexType, node), node);
        }
        function checkThatExpressionIsProperSymbolReference(expression, expressionType, reportError) {
            if (expressionType === unknownType) {
                // There is already an error, so no need to report one.
                return false;
            }
            if (!ts.isWellKnownSymbolSyntactically(expression)) {
                return false;
            }
            // Make sure the property type is the primitive symbol type
            if ((expressionType.flags & 512 /* ESSymbol */) === 0) {
                if (reportError) {
                    error(expression, ts.Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, ts.getTextOfNode(expression));
                }
                return false;
            }
            // The name is Symbol.<someName>, so make sure Symbol actually resolves to the
            // global Symbol object
            var leftHandSide = expression.expression;
            var leftHandSideSymbol = getResolvedSymbol(leftHandSide);
            if (!leftHandSideSymbol) {
                return false;
            }
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true);
            if (!globalESSymbol) {
                // Already errored when we tried to look up the symbol
                return false;
            }
            if (leftHandSideSymbol !== globalESSymbol) {
                if (reportError) {
                    error(leftHandSide, ts.Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
                }
                return false;
            }
            return true;
        }
        function callLikeExpressionMayHaveTypeArguments(node) {
            // TODO: Also include tagged templates (https://github.com/Microsoft/TypeScript/issues/11947)
            return ts.isCallOrNewExpression(node);
        }
        function resolveUntypedCall(node) {
            if (callLikeExpressionMayHaveTypeArguments(node)) {
                // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
                // This gets us diagnostics for the type arguments and marks them as referenced.
                ts.forEach(node.typeArguments, checkSourceElement);
            }
            if (node.kind === 183 /* TaggedTemplateExpression */) {
                checkExpression(node.template);
            }
            else if (node.kind !== 147 /* Decorator */) {
                ts.forEach(node.arguments, function (argument) {
                    checkExpression(argument);
                });
            }
            return anySignature;
        }
        function resolveErrorCall(node) {
            resolveUntypedCall(node);
            return unknownSignature;
        }
        // Re-order candidate signatures into the result array. Assumes the result array to be empty.
        // The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
        // A nit here is that we reorder only signatures that belong to the same symbol,
        // so order how inherited signatures are processed is still preserved.
        // interface A { (x: string): void }
        // interface B extends A { (x: 'foo'): string }
        // const b: B;
        // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
        function reorderCandidates(signatures, result) {
            var lastParent;
            var lastSymbol;
            var cutoffIndex = 0;
            var index;
            var specializedIndex = -1;
            var spliceIndex;
            ts.Debug.assert(!result.length);
            for (var _i = 0, signatures_4 = signatures; _i < signatures_4.length; _i++) {
                var signature = signatures_4[_i];
                var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
                var parent = signature.declaration && signature.declaration.parent;
                if (!lastSymbol || symbol === lastSymbol) {
                    if (lastParent && parent === lastParent) {
                        index++;
                    }
                    else {
                        lastParent = parent;
                        index = cutoffIndex;
                    }
                }
                else {
                    // current declaration belongs to a different symbol
                    // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
                    index = cutoffIndex = result.length;
                    lastParent = parent;
                }
                lastSymbol = symbol;
                // specialized signatures always need to be placed before non-specialized signatures regardless
                // of the cutoff position; see GH#1133
                if (signature.hasLiteralTypes) {
                    specializedIndex++;
                    spliceIndex = specializedIndex;
                    // The cutoff index always needs to be greater than or equal to the specialized signature index
                    // in order to prevent non-specialized signatures from being added before a specialized
                    // signature.
                    cutoffIndex++;
                }
                else {
                    spliceIndex = index;
                }
                result.splice(spliceIndex, 0, signature);
            }
        }
        function getSpreadArgumentIndex(args) {
            for (var i = 0; i < args.length; i++) {
                var arg = args[i];
                if (arg && arg.kind === 198 /* SpreadElement */) {
                    return i;
                }
            }
            return -1;
        }
        function hasCorrectArity(node, args, signature, signatureHelpTrailingComma) {
            if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
            var argCount; // Apparent number of arguments we will have in this call
            var typeArguments; // Type arguments (undefined if none)
            var callIsIncomplete; // In incomplete call we want to be lenient when we have too few arguments
            var spreadArgIndex = -1;
            if (ts.isJsxOpeningLikeElement(node)) {
                // The arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement".
                return true;
            }
            if (node.kind === 183 /* TaggedTemplateExpression */) {
                var tagExpression = node;
                // Even if the call is incomplete, we'll have a missing expression as our last argument,
                // so we can say the count is just the arg list length
                argCount = args.length;
                typeArguments = undefined;
                if (tagExpression.template.kind === 196 /* TemplateExpression */) {
                    // If a tagged template expression lacks a tail literal, the call is incomplete.
                    // Specifically, a template only can end in a TemplateTail or a Missing literal.
                    var templateExpression = tagExpression.template;
                    var lastSpan = ts.lastOrUndefined(templateExpression.templateSpans);
                    ts.Debug.assert(lastSpan !== undefined); // we should always have at least one span.
                    callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated;
                }
                else {
                    // If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
                    // then this might actually turn out to be a TemplateHead in the future;
                    // so we consider the call to be incomplete.
                    var templateLiteral = tagExpression.template;
                    ts.Debug.assert(templateLiteral.kind === 13 /* NoSubstitutionTemplateLiteral */);
                    callIsIncomplete = !!templateLiteral.isUnterminated;
                }
            }
            else if (node.kind === 147 /* Decorator */) {
                typeArguments = undefined;
                argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
            }
            else {
                var callExpression = node;
                if (!callExpression.arguments) {
                    // This only happens when we have something of the form: 'new C'
                    ts.Debug.assert(callExpression.kind === 182 /* NewExpression */);
                    return signature.minArgumentCount === 0;
                }
                argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
                // If we are missing the close parenthesis, the call is incomplete.
                callIsIncomplete = callExpression.arguments.end === callExpression.end;
                typeArguments = callExpression.typeArguments;
                spreadArgIndex = getSpreadArgumentIndex(args);
            }
            // If the user supplied type arguments, but the number of type arguments does not match
            // the declared number of type parameters, the call has an incorrect arity.
            var numTypeParameters = ts.length(signature.typeParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
            var hasRightNumberOfTypeArgs = !typeArguments ||
                (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
            if (!hasRightNumberOfTypeArgs) {
                return false;
            }
            // If spread arguments are present, check that they correspond to a rest parameter. If so, no
            // further checking is necessary.
            if (spreadArgIndex >= 0) {
                return isRestParameterIndex(signature, spreadArgIndex) || spreadArgIndex >= signature.minArgumentCount;
            }
            // Too many arguments implies incorrect arity.
            if (!signature.hasRestParameter && argCount > signature.parameters.length) {
                return false;
            }
            // If the call is incomplete, we should skip the lower bound check.
            var hasEnoughArguments = argCount >= signature.minArgumentCount;
            return callIsIncomplete || hasEnoughArguments;
        }
        // If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
        function getSingleCallSignature(type) {
            if (type.flags & 32768 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 &&
                    resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                    return resolved.callSignatures[0];
                }
            }
            return undefined;
        }
        // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
        function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) {
            var context = createInferenceContext(signature, 1 /* InferUnionTypes */, compareTypes);
            forEachMatchingParameterType(contextualSignature, signature, function (source, target) {
                // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
                inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);
            });
            if (!contextualMapper) {
                inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), 8 /* ReturnType */);
            }
            return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJavaScriptFile(contextualSignature.declaration));
        }
        function inferTypeArguments(node, signature, args, excludeArgument, context) {
            // Clear out all the inference results from the last time inferTypeArguments was called on this context
            for (var _i = 0, _a = context.inferences; _i < _a.length; _i++) {
                var inference = _a[_i];
                // As an optimization, we don't have to clear (and later recompute) inferred types
                // for type parameters that have already been fixed on the previous call to inferTypeArguments.
                // It would be just as correct to reset all of them. But then we'd be repeating the same work
                // for the type parameters that were fixed, namely the work done by getInferredType.
                if (!inference.isFixed) {
                    inference.inferredType = undefined;
                }
            }
            // If a contextual type is available, infer from that type to the return type of the call expression. For
            // example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
            // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
            // return type of 'wrap'.
            if (node.kind !== 147 /* Decorator */) {
                var contextualType = getContextualType(node);
                if (contextualType) {
                    // We clone the contextual mapper to avoid disturbing a resolution in progress for an
                    // outer call expression. Effectively we just want a snapshot of whatever has been
                    // inferred for any outer call expression so far.
                    var instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node)));
                    // If the contextual type is a generic function type with a single call signature, we
                    // instantiate the type with its own type parameters and type arguments. This ensures that
                    // the type parameters are not erased to type any during type inference such that they can
                    // be inferred as actual types from the contextual type. For example:
                    //   declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
                    //   const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
                    // Above, the type of the 'value' parameter is inferred to be 'A'.
                    var contextualSignature = getSingleCallSignature(instantiatedType);
                    var inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
                        getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters, ts.isInJavaScriptFile(node))) :
                        instantiatedType;
                    var inferenceTargetType = getReturnTypeOfSignature(signature);
                    // Inferences made from return types have lower priority than all other inferences.
                    inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, 8 /* ReturnType */);
                }
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType) {
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                inferTypes(context.inferences, thisArgumentType, thisType);
            }
            // We perform two passes over the arguments. In the first pass we infer from all arguments, but use
            // wildcards for all context sensitive function expressions.
            var argCount = getEffectiveArgumentCount(node, args, signature);
            for (var i = 0; i < argCount; i++) {
                var arg = getEffectiveArgument(node, args, i);
                // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
                if (arg === undefined || arg.kind !== 200 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = getEffectiveArgumentType(node, i);
                    // If the effective argument type is 'undefined', there is no synthetic type
                    // for the argument. In that case, we should check the argument.
                    if (argType === undefined) {
                        // For context sensitive arguments we pass the identityMapper, which is a signal to treat all
                        // context sensitive function expressions as wildcards
                        var mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context;
                        argType = checkExpressionWithContextualType(arg, paramType, mapper);
                    }
                    inferTypes(context.inferences, argType, paramType);
                }
            }
            // In the second pass we visit only context sensitive arguments, and only those that aren't excluded, this
            // time treating function expressions normally (which may cause previously inferred type arguments to be fixed
            // as we construct types for contextually typed parameters)
            // Decorators will not have `excludeArgument`, as their arguments cannot be contextually typed.
            // Tagged template expressions will always have `undefined` for `excludeArgument[0]`.
            if (excludeArgument) {
                for (var i = 0; i < argCount; i++) {
                    // No need to check for omitted args and template expressions, their exclusion value is always undefined
                    if (excludeArgument[i] === false) {
                        var arg = args[i];
                        var paramType = getTypeAtPosition(signature, i);
                        inferTypes(context.inferences, checkExpressionWithContextualType(arg, paramType, context), paramType);
                    }
                }
            }
            return getInferredTypes(context);
        }
        function checkTypeArguments(signature, typeArgumentNodes, reportErrors, headMessage) {
            var isJavascript = ts.isInJavaScriptFile(signature.declaration);
            var typeParameters = signature.typeParameters;
            var typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript);
            var mapper;
            for (var i = 0; i < typeArgumentNodes.length; i++) {
                ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments");
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (!constraint)
                    continue;
                var errorInfo = reportErrors && headMessage && ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                var typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
                if (!mapper) {
                    mapper = createTypeMapper(typeParameters, typeArgumentTypes);
                }
                var typeArgument = typeArgumentTypes[i];
                if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) {
                    return false;
                }
            }
            return typeArgumentTypes;
        }
        /**
         * Check if the given signature can possibly be a signature called by the JSX opening-like element.
         * @param node a JSX opening-like element we are trying to figure its call signature
         * @param signature a candidate signature we are trying whether it is a call signature
         * @param relation a relationship to check parameter and argument type
         * @param excludeArgument
         */
        function checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation) {
            // JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true:
            //      1. callIsIncomplete
            //      2. attributes property has same number of properties as the parameter object type.
            //         We can figure that out by resolving attributes property and check number of properties in the resolved type
            // If the call has correct arity, we will then check if the argument type and parameter type is assignable
            var callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incomplete
            if (callIsIncomplete) {
                return true;
            }
            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
            // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
            // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
            // can be specified by users through attributes property.
            var paramType = getTypeAtPosition(signature, 0);
            var attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined);
            var argProperties = getPropertiesOfType(attributesType);
            for (var _i = 0, argProperties_1 = argProperties; _i < argProperties_1.length; _i++) {
                var arg = argProperties_1[_i];
                if (!getPropertyOfType(paramType, arg.escapedName) && isUnhyphenatedJsxName(arg.escapedName)) {
                    return false;
                }
            }
            return checkTypeRelatedTo(attributesType, paramType, relation, /*errorNode*/ undefined, headMessage);
        }
        function checkApplicableSignature(node, args, signature, relation, excludeArgument, reportErrors) {
            if (ts.isJsxOpeningLikeElement(node)) {
                return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation);
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType && thisType !== voidType && node.kind !== 182 /* NewExpression */) {
                // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
                // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
                // If the expression is a new expression, then the check is skipped.
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                var errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
                var headMessage_1 = ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
                if (!checkTypeRelatedTo(thisArgumentType, getThisTypeOfSignature(signature), relation, errorNode, headMessage_1)) {
                    return false;
                }
            }
            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
            var argCount = getEffectiveArgumentCount(node, args, signature);
            for (var i = 0; i < argCount; i++) {
                var arg = getEffectiveArgument(node, args, i);
                // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
                if (arg === undefined || arg.kind !== 200 /* OmittedExpression */) {
                    // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
                    var paramType = getTypeAtPosition(signature, i);
                    // If the effective argument type is undefined, there is no synthetic type for the argument.
                    // In that case, we should check the argument.
                    var argType = getEffectiveArgumentType(node, i) ||
                        checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
                    // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
                    // we obtain the regular type of any object literal arguments because we may not have inferred complete
                    // parameter types yet and therefore excess property checks may yield false positives (see #17041).
                    var checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
                    // Use argument expression as error location when reporting errors
                    var errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined;
                    if (!checkTypeRelatedTo(checkArgType, paramType, relation, errorNode, headMessage)) {
                        return false;
                    }
                }
            }
            return true;
        }
        /**
         * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise.
         */
        function getThisArgumentOfCall(node) {
            if (node.kind === 181 /* CallExpression */) {
                var callee = node.expression;
                if (callee.kind === 179 /* PropertyAccessExpression */) {
                    return callee.expression;
                }
                else if (callee.kind === 180 /* ElementAccessExpression */) {
                    return callee.expression;
                }
            }
        }
        /**
         * Returns the effective arguments for an expression that works like a function invocation.
         *
         * If 'node' is a CallExpression or a NewExpression, then its argument list is returned.
         * If 'node' is a TaggedTemplateExpression, a new argument list is constructed from the substitution
         *    expressions, where the first element of the list is `undefined`.
         * If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types
         *    will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`.
         */
        function getEffectiveCallArguments(node) {
            if (node.kind === 183 /* TaggedTemplateExpression */) {
                var template = node.template;
                var args_4 = [undefined];
                if (template.kind === 196 /* TemplateExpression */) {
                    ts.forEach(template.templateSpans, function (span) {
                        args_4.push(span.expression);
                    });
                }
                return args_4;
            }
            else if (node.kind === 147 /* Decorator */) {
                // For a decorator, we return undefined as we will determine
                // the number and types of arguments for a decorator using
                // `getEffectiveArgumentCount` and `getEffectiveArgumentType` below.
                return undefined;
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                return node.attributes.properties.length > 0 ? [node.attributes] : ts.emptyArray;
            }
            else {
                return node.arguments || ts.emptyArray;
            }
        }
        /**
         * Returns the effective argument count for a node that works like a function invocation.
         * If 'node' is a Decorator, the number of arguments is derived from the decoration
         *    target and the signature:
         *    If 'node.target' is a class declaration or class expression, the effective argument
         *       count is 1.
         *    If 'node.target' is a parameter declaration, the effective argument count is 3.
         *    If 'node.target' is a property declaration, the effective argument count is 2.
         *    If 'node.target' is a method or accessor declaration, the effective argument count
         *       is 3, although it can be 2 if the signature only accepts two arguments, allowing
         *       us to match a property decorator.
         * Otherwise, the argument count is the length of the 'args' array.
         */
        function getEffectiveArgumentCount(node, args, signature) {
            if (node.kind === 147 /* Decorator */) {
                switch (node.parent.kind) {
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                        // A class decorator will have one argument (see `ClassDecorator` in core.d.ts)
                        return 1;
                    case 149 /* PropertyDeclaration */:
                        // A property declaration decorator will have two arguments (see
                        // `PropertyDecorator` in core.d.ts)
                        return 2;
                    case 151 /* MethodDeclaration */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        // A method or accessor declaration decorator will have two or three arguments (see
                        // `PropertyDecorator` and `MethodDecorator` in core.d.ts)
                        // If we are emitting decorators for ES3, we will only pass two arguments.
                        if (languageVersion === 0 /* ES3 */) {
                            return 2;
                        }
                        // If the method decorator signature only accepts a target and a key, we will only
                        // type check those arguments.
                        return signature.parameters.length >= 3 ? 3 : 2;
                    case 146 /* Parameter */:
                        // A parameter declaration decorator will have three arguments (see
                        // `ParameterDecorator` in core.d.ts)
                        return 3;
                }
            }
            else {
                return args.length;
            }
        }
        /**
         * Returns the effective type of the first argument to a decorator.
         * If 'node' is a class declaration or class expression, the effective argument type
         *    is the type of the static side of the class.
         * If 'node' is a parameter declaration, the effective argument type is either the type
         *    of the static or instance side of the class for the parameter's parent method,
         *    depending on whether the method is declared static.
         *    For a constructor, the type is always the type of the static side of the class.
         * If 'node' is a property, method, or accessor declaration, the effective argument
         *    type is the type of the static or instance side of the parent class for class
         *    element, depending on whether the element is declared static.
         */
        function getEffectiveDecoratorFirstArgumentType(node) {
            // The first argument to a decorator is its `target`.
            if (node.kind === 229 /* ClassDeclaration */) {
                // For a class decorator, the `target` is the type of the class (e.g. the
                // "static" or "constructor" side of the class)
                var classSymbol = getSymbolOfNode(node);
                return getTypeOfSymbol(classSymbol);
            }
            if (node.kind === 146 /* Parameter */) {
                // For a parameter decorator, the `target` is the parent type of the
                // parameter's containing method.
                node = node.parent;
                if (node.kind === 152 /* Constructor */) {
                    var classSymbol = getSymbolOfNode(node);
                    return getTypeOfSymbol(classSymbol);
                }
            }
            if (node.kind === 149 /* PropertyDeclaration */ ||
                node.kind === 151 /* MethodDeclaration */ ||
                node.kind === 153 /* GetAccessor */ ||
                node.kind === 154 /* SetAccessor */) {
                // For a property or method decorator, the `target` is the
                // "static"-side type of the parent of the member if the member is
                // declared "static"; otherwise, it is the "instance"-side type of the
                // parent of the member.
                return getParentTypeOfClassElement(node);
            }
            ts.Debug.fail("Unsupported decorator target.");
            return unknownType;
        }
        /**
         * Returns the effective type for the second argument to a decorator.
         * If 'node' is a parameter, its effective argument type is one of the following:
         *    If 'node.parent' is a constructor, the effective argument type is 'any', as we
         *       will emit `undefined`.
         *    If 'node.parent' is a member with an identifier, numeric, or string literal name,
         *       the effective argument type will be a string literal type for the member name.
         *    If 'node.parent' is a computed property name, the effective argument type will
         *       either be a symbol type or the string type.
         * If 'node' is a member with an identifier, numeric, or string literal name, the
         *    effective argument type will be a string literal type for the member name.
         * If 'node' is a computed property name, the effective argument type will either
         *    be a symbol type or the string type.
         * A class decorator does not have a second argument type.
         */
        function getEffectiveDecoratorSecondArgumentType(node) {
            // The second argument to a decorator is its `propertyKey`
            if (node.kind === 229 /* ClassDeclaration */) {
                ts.Debug.fail("Class decorators should not have a second synthetic argument.");
                return unknownType;
            }
            if (node.kind === 146 /* Parameter */) {
                node = node.parent;
                if (node.kind === 152 /* Constructor */) {
                    // For a constructor parameter decorator, the `propertyKey` will be `undefined`.
                    return anyType;
                }
                // For a non-constructor parameter decorator, the `propertyKey` will be either
                // a string or a symbol, based on the name of the parameter's containing method.
            }
            if (node.kind === 149 /* PropertyDeclaration */ ||
                node.kind === 151 /* MethodDeclaration */ ||
                node.kind === 153 /* GetAccessor */ ||
                node.kind === 154 /* SetAccessor */) {
                // The `propertyKey` for a property or method decorator will be a
                // string literal type if the member name is an identifier, number, or string;
                // otherwise, if the member name is a computed property name it will
                // be either string or symbol.
                var element = node;
                switch (element.name.kind) {
                    case 71 /* Identifier */:
                        return getLiteralType(ts.idText(element.name));
                    case 8 /* NumericLiteral */:
                    case 9 /* StringLiteral */:
                        return getLiteralType(element.name.text);
                    case 144 /* ComputedPropertyName */:
                        var nameType = checkComputedPropertyName(element.name);
                        if (isTypeAssignableToKind(nameType, 512 /* ESSymbol */)) {
                            return nameType;
                        }
                        else {
                            return stringType;
                        }
                    default:
                        ts.Debug.fail("Unsupported property name.");
                        return unknownType;
                }
            }
            ts.Debug.fail("Unsupported decorator target.");
            return unknownType;
        }
        /**
         * Returns the effective argument type for the third argument to a decorator.
         * If 'node' is a parameter, the effective argument type is the number type.
         * If 'node' is a method or accessor, the effective argument type is a
         *    `TypedPropertyDescriptor<T>` instantiated with the type of the member.
         * Class and property decorators do not have a third effective argument.
         */
        function getEffectiveDecoratorThirdArgumentType(node) {
            // The third argument to a decorator is either its `descriptor` for a method decorator
            // or its `parameterIndex` for a parameter decorator
            if (node.kind === 229 /* ClassDeclaration */) {
                ts.Debug.fail("Class decorators should not have a third synthetic argument.");
                return unknownType;
            }
            if (node.kind === 146 /* Parameter */) {
                // The `parameterIndex` for a parameter decorator is always a number
                return numberType;
            }
            if (node.kind === 149 /* PropertyDeclaration */) {
                ts.Debug.fail("Property decorators should not have a third synthetic argument.");
                return unknownType;
            }
            if (node.kind === 151 /* MethodDeclaration */ ||
                node.kind === 153 /* GetAccessor */ ||
                node.kind === 154 /* SetAccessor */) {
                // The `descriptor` for a method decorator will be a `TypedPropertyDescriptor<T>`
                // for the type of the member.
                var propertyType = getTypeOfNode(node);
                return createTypedPropertyDescriptorType(propertyType);
            }
            ts.Debug.fail("Unsupported decorator target.");
            return unknownType;
        }
        /**
         * Returns the effective argument type for the provided argument to a decorator.
         */
        function getEffectiveDecoratorArgumentType(node, argIndex) {
            if (argIndex === 0) {
                return getEffectiveDecoratorFirstArgumentType(node.parent);
            }
            else if (argIndex === 1) {
                return getEffectiveDecoratorSecondArgumentType(node.parent);
            }
            else if (argIndex === 2) {
                return getEffectiveDecoratorThirdArgumentType(node.parent);
            }
            ts.Debug.fail("Decorators should not have a fourth synthetic argument.");
            return unknownType;
        }
        /**
         * Gets the effective argument type for an argument in a call expression.
         */
        function getEffectiveArgumentType(node, argIndex) {
            // Decorators provide special arguments, a tagged template expression provides
            // a special first argument, and string literals get string literal types
            // unless we're reporting errors
            if (node.kind === 147 /* Decorator */) {
                return getEffectiveDecoratorArgumentType(node, argIndex);
            }
            else if (argIndex === 0 && node.kind === 183 /* TaggedTemplateExpression */) {
                return getGlobalTemplateStringsArrayType();
            }
            // This is not a synthetic argument, so we return 'undefined'
            // to signal that the caller needs to check the argument.
            return undefined;
        }
        /**
         * Gets the effective argument expression for an argument in a call expression.
         */
        function getEffectiveArgument(node, args, argIndex) {
            // For a decorator or the first argument of a tagged template expression we return undefined.
            if (node.kind === 147 /* Decorator */ ||
                (argIndex === 0 && node.kind === 183 /* TaggedTemplateExpression */)) {
                return undefined;
            }
            return args[argIndex];
        }
        /**
         * Gets the error node to use when reporting errors for an effective argument.
         */
        function getEffectiveArgumentErrorNode(node, argIndex, arg) {
            if (node.kind === 147 /* Decorator */) {
                // For a decorator, we use the expression of the decorator for error reporting.
                return node.expression;
            }
            else if (argIndex === 0 && node.kind === 183 /* TaggedTemplateExpression */) {
                // For a the first argument of a tagged template expression, we use the template of the tag for error reporting.
                return node.template;
            }
            else {
                return arg;
            }
        }
        function resolveCall(node, signatures, candidatesOutArray, fallbackError) {
            var isTaggedTemplate = node.kind === 183 /* TaggedTemplateExpression */;
            var isDecorator = node.kind === 147 /* Decorator */;
            var isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node);
            var typeArguments;
            if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
                typeArguments = node.typeArguments;
                // We already perform checking on the type arguments on the class declaration itself.
                if (node.expression.kind !== 97 /* SuperKeyword */) {
                    ts.forEach(typeArguments, checkSourceElement);
                }
            }
            var candidates = candidatesOutArray || [];
            // reorderCandidates fills up the candidates array directly
            reorderCandidates(signatures, candidates);
            if (!candidates.length) {
                diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures));
                return resolveErrorCall(node);
            }
            var args = getEffectiveCallArguments(node);
            // The following applies to any value of 'excludeArgument[i]':
            //    - true:      the argument at 'i' is susceptible to a one-time permanent contextual typing.
            //    - undefined: the argument at 'i' is *not* susceptible to permanent contextual typing.
            //    - false:     the argument at 'i' *was* and *has been* permanently contextually typed.
            //
            // The idea is that we will perform type argument inference & assignability checking once
            // without using the susceptible parameters that are functions, and once more for each of those
            // parameters, contextually typing each as we go along.
            //
            // For a tagged template, then the first argument be 'undefined' if necessary
            // because it represents a TemplateStringsArray.
            //
            // For a decorator, no arguments are susceptible to contextual typing due to the fact
            // decorators are applied to a declaration by the emitter, and not to an expression.
            var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
            var excludeArgument;
            var excludeCount = 0;
            if (!isDecorator && !isSingleNonGenericCandidate) {
                // We do not need to call `getEffectiveArgumentCount` here as it only
                // applies when calculating the number of arguments for a decorator.
                for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) {
                    if (isContextSensitive(args[i])) {
                        if (!excludeArgument) {
                            excludeArgument = new Array(args.length);
                        }
                        excludeArgument[i] = true;
                        excludeCount++;
                    }
                }
            }
            // The following variables are captured and modified by calls to chooseOverload.
            // If overload resolution or type argument inference fails, we want to report the
            // best error possible. The best error is one which says that an argument was not
            // assignable to a parameter. This implies that everything else about the overload
            // was fine. So if there is any overload that is only incorrect because of an
            // argument, we will report an error on that one.
            //
            //     function foo(s: string): void;
            //     function foo(n: number): void; // Report argument error on this overload
            //     function foo(): void;
            //     foo(true);
            //
            // If none of the overloads even made it that far, there are two possibilities.
            // There was a problem with type arguments for some overload, in which case
            // report an error on that. Or none of the overloads even had correct arity,
            // in which case give an arity error.
            //
            //     function foo<T extends string>(x: T): void; // Report type argument error
            //     function foo(): void;
            //     foo<number>(0);
            //
            var candidateForArgumentError;
            var candidateForTypeArgumentError;
            var result;
            // If we are in signature help, a trailing comma indicates that we intend to provide another argument,
            // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
            var signatureHelpTrailingComma = candidatesOutArray && node.kind === 181 /* CallExpression */ && node.arguments.hasTrailingComma;
            // Section 4.12.1:
            // if the candidate list contains one or more signatures for which the type of each argument
            // expression is a subtype of each corresponding parameter type, the return type of the first
            // of those signatures becomes the return type of the function call.
            // Otherwise, the return type of the first signature in the candidate list becomes the return
            // type of the function call.
            //
            // Whether the call is an error is determined by assignability of the arguments. The subtype pass
            // is just important for choosing the best signature. So in the case where there is only one
            // signature, the subtype pass is useless. So skipping it is an optimization.
            if (candidates.length > 1) {
                result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma);
            }
            if (!result) {
                result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
            }
            if (result) {
                return result;
            }
            // No signatures were applicable. Now report errors based on the last applicable signature with
            // no arguments excluded from assignability checks.
            // If candidate is undefined, it means that no candidates had a suitable arity. In that case,
            // skip the checkApplicableSignature check.
            if (candidateForArgumentError) {
                if (isJsxOpeningOrSelfClosingElement) {
                    // We do not report any error here because any error will be handled in "resolveCustomJsxElementAttributesType".
                    return candidateForArgumentError;
                }
                // excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...]
                // The importance of excludeArgument is to prevent us from typing function expression parameters
                // in arguments too early. If possible, we'd like to only type them once we know the correct
                // overload. However, this matters for the case where the call is correct. When the call is
                // an error, we don't need to exclude any arguments, although it would cause no harm to do so.
                checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
            }
            else if (candidateForTypeArgumentError) {
                checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true, fallbackError);
            }
            else if (typeArguments && ts.every(signatures, function (sig) { return ts.length(sig.typeParameters) !== typeArguments.length; })) {
                var min = Number.POSITIVE_INFINITY;
                var max = Number.NEGATIVE_INFINITY;
                for (var _i = 0, signatures_5 = signatures; _i < signatures_5.length; _i++) {
                    var sig = signatures_5[_i];
                    min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters));
                    max = Math.max(max, ts.length(sig.typeParameters));
                }
                var paramCount = min < max ? min + "-" + max : min;
                diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
            }
            else if (args) {
                var min = Number.POSITIVE_INFINITY;
                var max = Number.NEGATIVE_INFINITY;
                for (var _a = 0, signatures_6 = signatures; _a < signatures_6.length; _a++) {
                    var sig = signatures_6[_a];
                    min = Math.min(min, sig.minArgumentCount);
                    max = Math.max(max, sig.parameters.length);
                }
                var hasRestParameter_1 = ts.some(signatures, function (sig) { return sig.hasRestParameter; });
                var hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
                var paramCount = hasRestParameter_1 ? min :
                    min < max ? min + "-" + max :
                        min;
                var argCount = args.length - (hasSpreadArgument ? 1 : 0);
                var error_1 = hasRestParameter_1 && hasSpreadArgument ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_a_minimum_of_1 :
                    hasRestParameter_1 ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 :
                        hasSpreadArgument ? ts.Diagnostics.Expected_0_arguments_but_got_a_minimum_of_1 :
                            ts.Diagnostics.Expected_0_arguments_but_got_1;
                diagnostics.add(ts.createDiagnosticForNode(node, error_1, paramCount, argCount));
            }
            else if (fallbackError) {
                diagnostics.add(ts.createDiagnosticForNode(node, fallbackError));
            }
            // No signature was applicable. We have already reported the errors for the invalid signature.
            // If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
            // Pick the longest signature. This way we can get a contextual type for cases like:
            //     declare function f(a: { xa: number; xb: number; }, b: number);
            //     f({ |
            // Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
            //     declare function f<T>(k: keyof T);
            //     f<Foo>("
            if (!produceDiagnostics) {
                ts.Debug.assert(candidates.length > 0); // Else would have exited above.
                var bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount);
                var candidate = candidates[bestIndex];
                var typeParameters = candidate.typeParameters;
                if (typeParameters && callLikeExpressionMayHaveTypeArguments(node) && node.typeArguments) {
                    var typeArguments_1 = node.typeArguments.map(getTypeOfNode);
                    while (typeArguments_1.length > typeParameters.length) {
                        typeArguments_1.pop();
                    }
                    while (typeArguments_1.length < typeParameters.length) {
                        typeArguments_1.push(getDefaultTypeArgumentType(ts.isInJavaScriptFile(node)));
                    }
                    var instantiated = createSignatureInstantiation(candidate, typeArguments_1);
                    candidates[bestIndex] = instantiated;
                    return instantiated;
                }
                return candidate;
            }
            return resolveErrorCall(node);
            function chooseOverload(candidates, relation, signatureHelpTrailingComma) {
                if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
                candidateForArgumentError = undefined;
                candidateForTypeArgumentError = undefined;
                if (isSingleNonGenericCandidate) {
                    var candidate = candidates[0];
                    if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        return undefined;
                    }
                    if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
                        candidateForArgumentError = candidate;
                        return undefined;
                    }
                    return candidate;
                }
                for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
                    var originalCandidate = candidates[candidateIndex];
                    if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) {
                        continue;
                    }
                    var candidate = void 0;
                    var inferenceContext = originalCandidate.typeParameters ?
                        createInferenceContext(originalCandidate, /*flags*/ ts.isInJavaScriptFile(node) ? 4 /* AnyDefault */ : 0) :
                        undefined;
                    while (true) {
                        candidate = originalCandidate;
                        if (candidate.typeParameters) {
                            var typeArgumentTypes = void 0;
                            if (typeArguments) {
                                var typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
                                if (typeArgumentResult) {
                                    typeArgumentTypes = typeArgumentResult;
                                }
                                else {
                                    candidateForTypeArgumentError = originalCandidate;
                                    break;
                                }
                            }
                            else {
                                typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
                            }
                            var isJavascript = ts.isInJavaScriptFile(candidate.declaration);
                            candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript);
                        }
                        if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
                            candidateForArgumentError = candidate;
                            break;
                        }
                        if (excludeCount === 0) {
                            candidates[candidateIndex] = candidate;
                            return candidate;
                        }
                        excludeCount--;
                        if (excludeCount > 0) {
                            excludeArgument[ts.indexOf(excludeArgument, /*value*/ true)] = false;
                        }
                        else {
                            excludeArgument = undefined;
                        }
                    }
                }
                return undefined;
            }
        }
        function getLongestCandidateIndex(candidates, argsCount) {
            var maxParamsIndex = -1;
            var maxParams = -1;
            for (var i = 0; i < candidates.length; i++) {
                var candidate = candidates[i];
                if (candidate.hasRestParameter || candidate.parameters.length >= argsCount) {
                    return i;
                }
                if (candidate.parameters.length > maxParams) {
                    maxParams = candidate.parameters.length;
                    maxParamsIndex = i;
                }
            }
            return maxParamsIndex;
        }
        function resolveCallExpression(node, candidatesOutArray) {
            if (node.expression.kind === 97 /* SuperKeyword */) {
                var superType = checkSuperExpression(node.expression);
                if (superType !== unknownType) {
                    // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
                    // with the type arguments specified in the extends clause.
                    var baseTypeNode = ts.getClassExtendsHeritageClauseElement(ts.getContainingClass(node));
                    if (baseTypeNode) {
                        var baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
                        return resolveCall(node, baseConstructors, candidatesOutArray);
                    }
                }
                return resolveUntypedCall(node);
            }
            var funcType = checkNonNullExpression(node.expression);
            if (funcType === silentNeverType) {
                return silentNeverSignature;
            }
            var apparentType = getApparentType(funcType);
            if (apparentType === unknownType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including call signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
            // TS 1.0 Spec: 4.12
            // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
            // types are provided for the argument expressions, and the result is always of type Any.
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
                // The unknownType indicates that an error already occurred (and was reported).  No
                // need to report another error in this case.
                if (funcType !== unknownType && node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call.
            // TypeScript employs overload resolution in typed function calls in order to support functions
            // with multiple call signatures.
            if (!callSignatures.length) {
                if (constructSignatures.length) {
                    error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                }
                else {
                    error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
                }
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray);
        }
        /**
         * TS 1.0 spec: 4.12
         * If FuncExpr is of type Any, or of an object type that has no call or construct signatures
         * but is a subtype of the Function interface, the call is an untyped function call.
         */
        function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) {
            if (isTypeAny(funcType)) {
                return true;
            }
            if (isTypeAny(apparentFuncType) && funcType.flags & 16384 /* TypeParameter */) {
                return true;
            }
            if (!numCallSignatures && !numConstructSignatures) {
                // We exclude union types because we may have a union of function types that happen to have
                // no common signatures.
                if (funcType.flags & 65536 /* Union */) {
                    return false;
                }
                return isTypeAssignableTo(funcType, globalFunctionType);
            }
            return false;
        }
        function resolveNewExpression(node, candidatesOutArray) {
            if (node.arguments && languageVersion < 1 /* ES5 */) {
                var spreadIndex = getSpreadArgumentIndex(node.arguments);
                if (spreadIndex >= 0) {
                    error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher);
                }
            }
            var expressionType = checkNonNullExpression(node.expression);
            if (expressionType === silentNeverType) {
                return silentNeverSignature;
            }
            // If expressionType's apparent type(section 3.8.1) is an object type with one or
            // more construct signatures, the expression is processed in the same manner as a
            // function call, but using the construct signatures as the initial set of candidate
            // signatures for overload resolution. The result type of the function call becomes
            // the result type of the operation.
            expressionType = getApparentType(expressionType);
            if (expressionType === unknownType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // TS 1.0 spec: 4.11
            // If expressionType is of type Any, Args can be any argument
            // list and the result of the operation is of type Any.
            if (isTypeAny(expressionType)) {
                if (node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including construct signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */);
            if (constructSignatures.length) {
                if (!isConstructorAccessible(node, constructSignatures[0])) {
                    return resolveErrorCall(node);
                }
                // If the expression is a class of abstract type, then it cannot be instantiated.
                // Note, only class declarations can be declared abstract.
                // In the case of a merged class-module or class-interface declaration,
                // only the class declaration node will have the Abstract flag set.
                var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
                if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) {
                    error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl)));
                    return resolveErrorCall(node);
                }
                return resolveCall(node, constructSignatures, candidatesOutArray);
            }
            // If expressionType's apparent type is an object type with no construct signatures but
            // one or more call signatures, the expression is processed as a function call. A compile-time
            // error occurs if the result of the function call is not Void. The type of the result of the
            // operation is Any. It is an error to have a Void this type.
            var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */);
            if (callSignatures.length) {
                var signature = resolveCall(node, callSignatures, candidatesOutArray);
                if (!isJavaScriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
                    error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
                }
                if (getThisTypeOfSignature(signature) === voidType) {
                    error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void);
                }
                return signature;
            }
            error(node, ts.Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature);
            return resolveErrorCall(node);
        }
        function isConstructorAccessible(node, signature) {
            if (!signature || !signature.declaration) {
                return true;
            }
            var declaration = signature.declaration;
            var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */);
            // Public constructor is accessible.
            if (!modifiers) {
                return true;
            }
            var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
            var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol);
            // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
            if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                var containingClass = ts.getContainingClass(node);
                if (containingClass) {
                    var containingType = getTypeOfNode(containingClass);
                    var baseTypes = getBaseTypes(containingType);
                    while (baseTypes.length) {
                        var baseType = baseTypes[0];
                        if (modifiers & 16 /* Protected */ &&
                            baseType.symbol === declaration.parent.symbol) {
                            return true;
                        }
                        baseTypes = getBaseTypes(baseType);
                    }
                }
                if (modifiers & 8 /* Private */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                if (modifiers & 16 /* Protected */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                return false;
            }
            return true;
        }
        function resolveTaggedTemplateExpression(node, candidatesOutArray) {
            var tagType = checkExpression(node.tag);
            var apparentType = getApparentType(tagType);
            if (apparentType === unknownType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
            if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
                return resolveUntypedCall(node);
            }
            if (!callSignatures.length) {
                error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray);
        }
        /**
         * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.
         */
        function getDiagnosticHeadMessageForDecoratorResolution(node) {
            switch (node.parent.kind) {
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
                case 146 /* Parameter */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
                case 149 /* PropertyDeclaration */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
                case 151 /* MethodDeclaration */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression;
            }
        }
        /**
         * Resolves a decorator as if it were a call expression.
         */
        function resolveDecorator(node, candidatesOutArray) {
            var funcType = checkExpression(node.expression);
            var apparentType = getApparentType(funcType);
            if (apparentType === unknownType) {
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
                return resolveUntypedCall(node);
            }
            if (isPotentiallyUncalledDecorator(node, callSignatures)) {
                var nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false);
                error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr);
                return resolveErrorCall(node);
            }
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            if (!callSignatures.length) {
                var errorInfo = void 0;
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType));
                errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage);
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, errorInfo));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, headMessage);
        }
        /**
         * Sometimes, we have a decorator that could accept zero arguments,
         * but is receiving too many arguments as part of the decorator invocation.
         * In those cases, a user may have meant to *call* the expression before using it as a decorator.
         */
        function isPotentiallyUncalledDecorator(decorator, signatures) {
            return signatures.length && ts.every(signatures, function (signature) {
                return signature.minArgumentCount === 0 &&
                    !signature.hasRestParameter &&
                    signature.parameters.length < getEffectiveArgumentCount(decorator, /*args*/ undefined, signature);
            });
        }
        /**
         * This function is similar to getResolvedSignature but is exclusively for trying to resolve JSX stateless-function component.
         * The main reason we have to use this function instead of getResolvedSignature because, the caller of this function will already check the type of openingLikeElement's tagName
         * and pass the type as elementType. The elementType can not be a union (as such case should be handled by the caller of this function)
         * Note: at this point, we are still not sure whether the opening-like element is a stateless function component or not.
         * @param openingLikeElement an opening-like JSX element to try to resolve as JSX stateless function
         * @param elementType an element type of the opneing-like element by checking opening-like element's tagname.
         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
         *                           the function will fill it up with appropriate candidate signatures
         */
        function getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray) {
            ts.Debug.assert(!(elementType.flags & 65536 /* Union */));
            return resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray);
        }
        /**
         * Try treating a given opening-like element as stateless function component and resolve a tagName to a function signature.
         * @param openingLikeElement an JSX opening-like element we want to try resolve its stateless function if possible
         * @param elementType a type of the opening-like JSX element, a result of resolving tagName in opening-like element.
         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
         *                           the function will fill it up with appropriate candidate signatures
         * @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions.
         *         otherwise return undefined if tag-name of the opening-like element doesn't have call signatures
         */
        function resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray) {
            // If this function is called from language service, elementType can be a union type. This is not possible if the function is called from compiler (see: resolveCustomJsxElementAttributesType)
            if (elementType.flags & 65536 /* Union */) {
                var types = elementType.types;
                var result = void 0;
                for (var _i = 0, types_17 = types; _i < types_17.length; _i++) {
                    var type = types_17[_i];
                    result = result || resolveStatelessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray);
                }
                return result;
            }
            var callSignatures = elementType && getSignaturesOfType(elementType, 0 /* Call */);
            if (callSignatures && callSignatures.length > 0) {
                return resolveCall(openingLikeElement, callSignatures, candidatesOutArray);
            }
            return undefined;
        }
        function resolveSignature(node, candidatesOutArray) {
            switch (node.kind) {
                case 181 /* CallExpression */:
                    return resolveCallExpression(node, candidatesOutArray);
                case 182 /* NewExpression */:
                    return resolveNewExpression(node, candidatesOutArray);
                case 183 /* TaggedTemplateExpression */:
                    return resolveTaggedTemplateExpression(node, candidatesOutArray);
                case 147 /* Decorator */:
                    return resolveDecorator(node, candidatesOutArray);
                case 251 /* JsxOpeningElement */:
                case 250 /* JsxSelfClosingElement */:
                    // This code-path is called by language service
                    return resolveStatelessJsxOpeningLikeElement(node, checkExpression(node.tagName), candidatesOutArray) || unknownSignature;
            }
            ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
        }
        /**
         * Resolve a signature of a given call-like expression.
         * @param node a call-like expression to try resolve a signature for
         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
         *                           the function will fill it up with appropriate candidate signatures
         * @return a signature of the call-like expression or undefined if one can't be found
         */
        function getResolvedSignature(node, candidatesOutArray) {
            var links = getNodeLinks(node);
            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
            // However, it is possible that either candidatesOutArray was not passed in the first time,
            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
            // to correctly fill the candidatesOutArray.
            var cached = links.resolvedSignature;
            if (cached && cached !== resolvingSignature && !candidatesOutArray) {
                return cached;
            }
            links.resolvedSignature = resolvingSignature;
            var result = resolveSignature(node, candidatesOutArray);
            // If signature resolution originated in control flow type analysis (for example to compute the
            // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
            // types from the control flow analysis.
            links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
            return result;
        }
        /**
         * Indicates whether a declaration can be treated as a constructor in a JavaScript
         * file.
         */
        function isJavaScriptConstructor(node) {
            if (node && ts.isInJavaScriptFile(node)) {
                // If the node has a @class tag, treat it like a constructor.
                if (ts.getJSDocClassTag(node))
                    return true;
                // If the symbol of the node has members, treat it like a constructor.
                var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) :
                    ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) :
                        undefined;
                return symbol && symbol.members !== undefined;
            }
            return false;
        }
        function getJavaScriptClassType(symbol) {
            if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
                symbol = getSymbolOfNode(symbol.valueDeclaration.initializer);
            }
            if (isJavaScriptConstructor(symbol.valueDeclaration)) {
                return getInferredClassType(symbol);
            }
            if (symbol.flags & 3 /* Variable */) {
                var valueType = getTypeOfSymbol(symbol);
                if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
                    return getInferredClassType(valueType.symbol);
                }
            }
        }
        function getInferredClassType(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.inferredClassType) {
                links.inferredClassType = createAnonymousType(symbol, symbol.members || emptySymbols, ts.emptyArray, ts.emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
            }
            return links.inferredClassType;
        }
        function isInferredClassType(type) {
            return type.symbol
                && getObjectFlags(type) & 16 /* Anonymous */
                && getSymbolLinks(type.symbol).inferredClassType === type;
        }
        /**
         * Syntactically and semantically checks a call or new expression.
         * @param node The call/new expression to be checked.
         * @returns On success, the expression's signature's return type. On failure, anyType.
         */
        function checkCallExpression(node) {
            // Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
            checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node.arguments);
            var signature = getResolvedSignature(node);
            if (node.expression.kind === 97 /* SuperKeyword */) {
                return voidType;
            }
            if (node.kind === 182 /* NewExpression */) {
                var declaration = signature.declaration;
                if (declaration &&
                    declaration.kind !== 152 /* Constructor */ &&
                    declaration.kind !== 156 /* ConstructSignature */ &&
                    declaration.kind !== 161 /* ConstructorType */ &&
                    !ts.isJSDocConstructSignature(declaration)) {
                    // When resolved signature is a call signature (and not a construct signature) the result type is any, unless
                    // the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations
                    // in a JS file
                    // Note:JS inferred classes might come from a variable declaration instead of a function declaration.
                    // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
                    var funcSymbol = checkExpression(node.expression).symbol;
                    if (!funcSymbol && node.expression.kind === 71 /* Identifier */) {
                        funcSymbol = getResolvedSymbol(node.expression);
                    }
                    var type = funcSymbol && getJavaScriptClassType(funcSymbol);
                    if (type) {
                        return type;
                    }
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                    }
                    return anyType;
                }
            }
            // In JavaScript files, calls to any identifier 'require' are treated as external module imports
            if (ts.isInJavaScriptFile(node) && isCommonJsRequire(node)) {
                return resolveExternalModuleTypeByLiteral(node.arguments[0]);
            }
            return getReturnTypeOfSignature(signature);
        }
        function checkImportCallExpression(node) {
            // Check grammar of dynamic import
            checkGrammarArguments(node.arguments) || checkGrammarImportCallExpression(node);
            if (node.arguments.length === 0) {
                return createPromiseReturnType(node, anyType);
            }
            var specifier = node.arguments[0];
            var specifierType = checkExpressionCached(specifier);
            // Even though multiple arugments is grammatically incorrect, type-check extra arguments for completion
            for (var i = 1; i < node.arguments.length; ++i) {
                checkExpressionCached(node.arguments[i]);
            }
            if (specifierType.flags & 2048 /* Undefined */ || specifierType.flags & 4096 /* Null */ || !isTypeAssignableTo(specifierType, stringType)) {
                error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
            }
            // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
            var moduleSymbol = resolveExternalModuleName(node, specifier);
            if (moduleSymbol) {
                var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true);
                if (esModuleSymbol) {
                    return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol));
                }
            }
            return createPromiseReturnType(node, anyType);
        }
        function getTypeWithSyntheticDefaultImportType(type, symbol) {
            if (allowSyntheticDefaultImports && type && type !== unknownType) {
                var synthType = type;
                if (!synthType.syntheticType) {
                    if (!getPropertyOfType(type, "default" /* Default */)) {
                        var memberTable = ts.createSymbolTable();
                        var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */);
                        newSymbol.target = resolveSymbol(symbol);
                        memberTable.set("default" /* Default */, newSymbol);
                        var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
                        var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                        anonymousSymbol.type = defaultContainingObject;
                        synthType.syntheticType = getIntersectionType([type, defaultContainingObject]);
                    }
                    else {
                        synthType.syntheticType = type;
                    }
                }
                return synthType.syntheticType;
            }
            return type;
        }
        function isCommonJsRequire(node) {
            if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
                return false;
            }
            // Make sure require is not a local function
            if (!ts.isIdentifier(node.expression))
                throw ts.Debug.fail();
            var resolvedRequire = resolveName(node.expression, node.expression.escapedText, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
            if (!resolvedRequire) {
                // project does not contain symbol named 'require' - assume commonjs require
                return true;
            }
            // project includes symbol named 'require' - make sure that it it ambient and local non-alias
            if (resolvedRequire.flags & 2097152 /* Alias */) {
                return false;
            }
            var targetDeclarationKind = resolvedRequire.flags & 16 /* Function */
                ? 228 /* FunctionDeclaration */
                : resolvedRequire.flags & 3 /* Variable */
                    ? 226 /* VariableDeclaration */
                    : 0 /* Unknown */;
            if (targetDeclarationKind !== 0 /* Unknown */) {
                var decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
                // function/variable declaration should be ambient
                return ts.isInAmbientContext(decl);
            }
            return false;
        }
        function checkTaggedTemplateExpression(node) {
            if (languageVersion < 2 /* ES2015 */) {
                checkExternalEmitHelpers(node, 65536 /* MakeTemplateObject */);
            }
            return getReturnTypeOfSignature(getResolvedSignature(node));
        }
        function checkAssertion(node) {
            return checkAssertionWorker(node, node.type, node.expression);
        }
        function checkAssertionWorker(errNode, type, expression, checkMode) {
            var exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(expression, checkMode)));
            checkSourceElement(type);
            var targetType = getTypeFromTypeNode(type);
            if (produceDiagnostics && targetType !== unknownType) {
                var widenedType = getWidenedType(exprType);
                if (!isTypeComparableTo(targetType, widenedType)) {
                    checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Type_0_cannot_be_converted_to_type_1);
                }
            }
            return targetType;
        }
        function checkNonNullAssertion(node) {
            return getNonNullableType(checkExpression(node.expression));
        }
        function checkMetaProperty(node) {
            checkGrammarMetaProperty(node);
            var container = ts.getNewTargetContainer(node);
            if (!container) {
                error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
                return unknownType;
            }
            else if (container.kind === 152 /* Constructor */) {
                var symbol = getSymbolOfNode(container.parent);
                return getTypeOfSymbol(symbol);
            }
            else {
                var symbol = getSymbolOfNode(container);
                return getTypeOfSymbol(symbol);
            }
        }
        function getTypeOfParameter(symbol) {
            var type = getTypeOfSymbol(symbol);
            if (strictNullChecks) {
                var declaration = symbol.valueDeclaration;
                if (declaration && declaration.initializer) {
                    return getNullableType(type, 2048 /* Undefined */);
                }
            }
            return type;
        }
        function getTypeAtPosition(signature, pos) {
            return signature.hasRestParameter ?
                pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
                pos < signature.parameters.length ? getTypeOfParameter(signature.parameters[pos]) : anyType;
        }
        function getTypeOfFirstParameterOfSignature(signature) {
            return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType;
        }
        function inferFromAnnotatedParameters(signature, context, mapper) {
            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var declaration = signature.parameters[i].valueDeclaration;
                if (declaration.type) {
                    var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
                    if (typeNode) {
                        inferTypes(mapper.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
                    }
                }
            }
        }
        function assignContextualParameterTypes(signature, context) {
            signature.typeParameters = context.typeParameters;
            if (context.thisParameter) {
                var parameter = signature.thisParameter;
                if (!parameter || parameter.valueDeclaration && !parameter.valueDeclaration.type) {
                    if (!parameter) {
                        signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
                    }
                    assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
                }
            }
            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var parameter = signature.parameters[i];
                if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = getTypeAtPosition(context, i);
                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                }
            }
            if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
                // parameter might be a transient symbol generated by use of `arguments` in the function body.
                var parameter = ts.lastOrUndefined(signature.parameters);
                if (isTransientSymbol(parameter) || !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = getTypeOfSymbol(ts.lastOrUndefined(context.parameters));
                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                }
            }
        }
        // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
        // the destructured type into the contained binding elements.
        function assignBindingElementTypes(pattern) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    if (element.name.kind === 71 /* Identifier */) {
                        getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
                    }
                    else {
                        assignBindingElementTypes(element.name);
                    }
                }
            }
        }
        function assignTypeToParameterAndFixTypeParameters(parameter, contextualType) {
            var links = getSymbolLinks(parameter);
            if (!links.type) {
                links.type = contextualType;
                var decl = parameter.valueDeclaration;
                if (decl.name.kind !== 71 /* Identifier */) {
                    // if inference didn't come up with anything but {}, fall back to the binding pattern if present.
                    if (links.type === emptyObjectType) {
                        links.type = getTypeFromBindingPattern(decl.name);
                    }
                    assignBindingElementTypes(decl.name);
                }
            }
        }
        function createPromiseType(promisedType) {
            // creates a `Promise<T>` type where `T` is the promisedType argument
            var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
            if (globalPromiseType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || emptyObjectType;
                return createTypeReference(globalPromiseType, [promisedType]);
            }
            return emptyObjectType;
        }
        function createPromiseReturnType(func, promisedType) {
            var promiseType = createPromiseType(promisedType);
            if (promiseType === emptyObjectType) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
                return unknownType;
            }
            else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
            }
            return promiseType;
        }
        function getReturnTypeFromBody(func, checkMode) {
            var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
            if (!func.body) {
                return unknownType;
            }
            var functionFlags = ts.getFunctionFlags(func);
            var type;
            if (func.body.kind !== 207 /* Block */) {
                type = checkExpressionCached(func.body, checkMode);
                if (functionFlags & 2 /* Async */) {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                    // return type of the body should be unwrapped to its awaited type, which we will wrap in
                    // the native Promise<T> type later in this function.
                    type = checkAwaitedType(type, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                }
            }
            else {
                var types = void 0;
                if (functionFlags & 1 /* Generator */) {
                    types = ts.concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), checkAndAggregateReturnExpressionTypes(func, checkMode));
                    if (!types || types.length === 0) {
                        var iterableIteratorAny = functionFlags & 2 /* Async */
                            ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function
                            : createIterableIteratorType(anyType); // Generator function
                        if (noImplicitAny) {
                            error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny));
                        }
                        return iterableIteratorAny;
                    }
                }
                else {
                    types = checkAndAggregateReturnExpressionTypes(func, checkMode);
                    if (!types) {
                        // For an async function, the return type will not be never, but rather a Promise for never.
                        return functionFlags & 2 /* Async */
                            ? createPromiseReturnType(func, neverType) // Async function
                            : neverType; // Normal function
                    }
                    if (types.length === 0) {
                        // For an async function, the return type will not be void, but rather a Promise for void.
                        return functionFlags & 2 /* Async */
                            ? createPromiseReturnType(func, voidType) // Async function
                            : voidType; // Normal function
                    }
                }
                // Return a union of the return expression types.
                type = getUnionType(types, /*subtypeReduction*/ true);
                if (functionFlags & 1 /* Generator */) {
                    type = functionFlags & 2 /* Async */
                        ? createAsyncIterableIteratorType(type) // AsyncGenerator function
                        : createIterableIteratorType(type); // Generator function
                }
            }
            if (!contextualSignature) {
                reportErrorsFromWidening(func, type);
            }
            if (isUnitType(type) &&
                !(contextualSignature &&
                    isLiteralContextualType(contextualSignature === getSignatureFromDeclaration(func) ? type : getReturnTypeOfSignature(contextualSignature)))) {
                type = getWidenedLiteralType(type);
            }
            var widenedType = getWidenedType(type);
            // From within an async function you can return either a non-promise value or a promise. Any
            // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
            // return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
            return (functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */
                ? createPromiseReturnType(func, widenedType) // Async function
                : widenedType; // Generator function, AsyncGenerator function, or normal function
        }
        function checkAndAggregateYieldOperandTypes(func, checkMode) {
            var aggregatedTypes = [];
            var functionFlags = ts.getFunctionFlags(func);
            ts.forEachYieldExpression(func.body, function (yieldExpression) {
                var expr = yieldExpression.expression;
                if (expr) {
                    var type = checkExpressionCached(expr, checkMode);
                    if (yieldExpression.asteriskToken) {
                        // A yield* expression effectively yields everything that its operand yields
                        type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & 2 /* Async */) !== 0);
                    }
                    if (functionFlags & 2 /* Async */) {
                        type = checkAwaitedType(type, expr, yieldExpression.asteriskToken
                            ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
                            : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                    }
                    ts.pushIfUnique(aggregatedTypes, type);
                }
            });
            return aggregatedTypes;
        }
        function isExhaustiveSwitchStatement(node) {
            if (!node.possiblyExhaustive) {
                return false;
            }
            var type = getTypeOfExpression(node.expression);
            if (!isLiteralType(type)) {
                return false;
            }
            var switchTypes = getSwitchClauseTypes(node);
            if (!switchTypes.length) {
                return false;
            }
            return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
        }
        function functionHasImplicitReturn(func) {
            if (!(func.flags & 128 /* HasImplicitReturn */)) {
                return false;
            }
            var lastStatement = ts.lastOrUndefined(func.body.statements);
            if (lastStatement && lastStatement.kind === 221 /* SwitchStatement */ && isExhaustiveSwitchStatement(lastStatement)) {
                return false;
            }
            return true;
        }
        function checkAndAggregateReturnExpressionTypes(func, checkMode) {
            var functionFlags = ts.getFunctionFlags(func);
            var aggregatedTypes = [];
            var hasReturnWithNoExpression = functionHasImplicitReturn(func);
            var hasReturnOfTypeNever = false;
            ts.forEachReturnStatement(func.body, function (returnStatement) {
                var expr = returnStatement.expression;
                if (expr) {
                    var type = checkExpressionCached(expr, checkMode);
                    if (functionFlags & 2 /* Async */) {
                        // From within an async function you can return either a non-promise value or a promise. Any
                        // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                        // return type of the body should be unwrapped to its awaited type, which should be wrapped in
                        // the native Promise<T> type by the caller.
                        type = checkAwaitedType(type, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                    }
                    if (type.flags & 8192 /* Never */) {
                        hasReturnOfTypeNever = true;
                    }
                    ts.pushIfUnique(aggregatedTypes, type);
                }
                else {
                    hasReturnWithNoExpression = true;
                }
            });
            if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever ||
                func.kind === 186 /* FunctionExpression */ || func.kind === 187 /* ArrowFunction */)) {
                return undefined;
            }
            if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) {
                ts.pushIfUnique(aggregatedTypes, undefinedType);
            }
            return aggregatedTypes;
        }
        /**
         * TypeScript Specification 1.0 (6.3) - July 2014
         *   An explicitly typed function whose return type isn't the Void type,
         *   the Any type, or a union type containing the Void or Any type as a constituent
         *   must have at least one return statement somewhere in its body.
         *   An exception to this rule is if the function implementation consists of a single 'throw' statement.
         *
         * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
         */
        function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func, returnType) {
            if (!produceDiagnostics) {
                return;
            }
            // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
            if (returnType && maybeTypeOfKind(returnType, 1 /* Any */ | 1024 /* Void */)) {
                return;
            }
            // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
            // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
            if (ts.nodeIsMissing(func.body) || func.body.kind !== 207 /* Block */ || !functionHasImplicitReturn(func)) {
                return;
            }
            var hasExplicitReturn = func.flags & 256 /* HasExplicitReturn */;
            if (returnType && returnType.flags & 8192 /* Never */) {
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
            }
            else if (returnType && !hasExplicitReturn) {
                // minimal check: function has syntactic return type annotation and no explicit return statements in the body
                // this function does not conform to the specification.
                // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
            }
            else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) {
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
            }
            else if (compilerOptions.noImplicitReturns) {
                if (!returnType) {
                    // If return type annotation is omitted check if function has any explicit return statements.
                    // If it does not have any - its inferred return type is void - don't do any checks.
                    // Otherwise get inferred return type from function body and report error only if it is not void / anytype
                    if (!hasExplicitReturn) {
                        return;
                    }
                    var inferredReturnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
                    if (isUnwrappedReturnTypeVoidOrAny(func, inferredReturnType)) {
                        return;
                    }
                }
                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            // The identityMapper object is used to indicate that function expressions are wildcards
            if (checkMode === 1 /* SkipContextSensitive */ && isContextSensitive(node)) {
                checkNodeDeferred(node);
                return anyFunctionType;
            }
            // Grammar checking
            var hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
            if (!hasGrammarError && node.kind === 186 /* FunctionExpression */) {
                checkGrammarForGenerator(node);
            }
            var links = getNodeLinks(node);
            var type = getTypeOfSymbol(node.symbol);
            // Check if function expression is contextually typed and assign parameter types if so.
            if (!(links.flags & 1024 /* ContextChecked */)) {
                var contextualSignature = getContextualSignature(node);
                // If a type check is started at a function expression that is an argument of a function call, obtaining the
                // contextual type may recursively get back to here during overload resolution of the call. If so, we will have
                // already assigned contextual types.
                if (!(links.flags & 1024 /* ContextChecked */)) {
                    links.flags |= 1024 /* ContextChecked */;
                    if (contextualSignature) {
                        var signature = getSignaturesOfType(type, 0 /* Call */)[0];
                        if (isContextSensitive(node)) {
                            var contextualMapper = getContextualMapper(node);
                            if (checkMode === 2 /* Inferential */) {
                                inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
                            }
                            var instantiatedContextualSignature = contextualMapper === identityMapper ?
                                contextualSignature : instantiateSignature(contextualSignature, contextualMapper);
                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
                        }
                        if (!ts.getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) {
                            var returnType = getReturnTypeFromBody(node, checkMode);
                            if (!signature.resolvedReturnType) {
                                signature.resolvedReturnType = returnType;
                            }
                        }
                    }
                    checkSignatureDeclaration(node);
                    checkNodeDeferred(node);
                }
            }
            if (produceDiagnostics && node.kind !== 151 /* MethodDeclaration */) {
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithCapturedNewTargetVariable(node, node.name);
            }
            return type;
        }
        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) {
            ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var functionFlags = ts.getFunctionFlags(node);
            var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
            var returnOrPromisedType = returnTypeNode &&
                ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ ?
                    checkAsyncFunctionReturnType(node) : // Async function
                    getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function
            if ((functionFlags & 1 /* Generator */) === 0) {
                // return is not necessary in the body of generators
                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
            }
            if (node.body) {
                if (!returnTypeNode) {
                    // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
                    // we need. An example is the noImplicitAny errors resulting from widening the return expression
                    // of a function. Because checking of function expression bodies is deferred, there was never an
                    // appropriate time to do this during the main walk of the file (see the comment at the top of
                    // checkFunctionExpressionBodies). So it must be done now.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
                if (node.body.kind === 207 /* Block */) {
                    checkSourceElement(node.body);
                }
                else {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so we
                    // should not be checking assignability of a promise to the return type. Instead, we need to
                    // check assignability of the awaited type of the expression body against the promised type of
                    // its return type annotation.
                    var exprType = checkExpression(node.body);
                    if (returnOrPromisedType) {
                        if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) {
                            var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                            checkTypeAssignableTo(awaitedType, returnOrPromisedType, node.body);
                        }
                        else {
                            checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
                        }
                    }
                }
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkArithmeticOperandType(operand, type, diagnostic) {
            if (!isTypeAssignableToKind(type, 84 /* NumberLike */)) {
                error(operand, diagnostic);
                return false;
            }
            return true;
        }
        function isReadonlySymbol(symbol) {
            // The following symbols are considered read-only:
            // Properties with a 'readonly' modifier
            // Variables declared with 'const'
            // Get accessors without matching set accessors
            // Enum members
            // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation)
            return !!(ts.getCheckFlags(symbol) & 8 /* Readonly */ ||
                symbol.flags & 4 /* Property */ && ts.getDeclarationModifierFlagsFromSymbol(symbol) & 64 /* Readonly */ ||
                symbol.flags & 3 /* Variable */ && getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */ ||
                symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) ||
                symbol.flags & 8 /* EnumMember */);
        }
        function isReferenceToReadonlyEntity(expr, symbol) {
            if (isReadonlySymbol(symbol)) {
                // Allow assignments to readonly properties within constructors of the same class declaration.
                if (symbol.flags & 4 /* Property */ &&
                    (expr.kind === 179 /* PropertyAccessExpression */ || expr.kind === 180 /* ElementAccessExpression */) &&
                    expr.expression.kind === 99 /* ThisKeyword */) {
                    // Look for if this is the constructor for the class that `symbol` is a property of.
                    var func = ts.getContainingFunction(expr);
                    if (!(func && func.kind === 152 /* Constructor */)) {
                        return true;
                    }
                    // If func.parent is a class and symbol is a (readonly) property of that class, or
                    // if func is a constructor and symbol is a (readonly) parameter property declared in it,
                    // then symbol is writeable here.
                    return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent);
                }
                return true;
            }
            return false;
        }
        function isReferenceThroughNamespaceImport(expr) {
            if (expr.kind === 179 /* PropertyAccessExpression */ || expr.kind === 180 /* ElementAccessExpression */) {
                var node = ts.skipParentheses(expr.expression);
                if (node.kind === 71 /* Identifier */) {
                    var symbol = getNodeLinks(node).resolvedSymbol;
                    if (symbol.flags & 2097152 /* Alias */) {
                        var declaration = getDeclarationOfAliasSymbol(symbol);
                        return declaration && declaration.kind === 240 /* NamespaceImport */;
                    }
                }
            }
            return false;
        }
        function checkReferenceExpression(expr, invalidReferenceMessage) {
            // References are combinations of identifiers, parentheses, and property accesses.
            var node = ts.skipOuterExpressions(expr, 2 /* Assertions */ | 1 /* Parentheses */);
            if (node.kind !== 71 /* Identifier */ && node.kind !== 179 /* PropertyAccessExpression */ && node.kind !== 180 /* ElementAccessExpression */) {
                error(expr, invalidReferenceMessage);
                return false;
            }
            return true;
        }
        function checkDeleteExpression(node) {
            checkExpression(node.expression);
            var expr = ts.skipParentheses(node.expression);
            if (expr.kind !== 179 /* PropertyAccessExpression */ && expr.kind !== 180 /* ElementAccessExpression */) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference);
                return booleanType;
            }
            var links = getNodeLinks(expr);
            var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol);
            if (symbol && isReadonlySymbol(symbol)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property);
            }
            return booleanType;
        }
        function checkTypeOfExpression(node) {
            checkExpression(node.expression);
            return typeofType;
        }
        function checkVoidExpression(node) {
            checkExpression(node.expression);
            return undefinedWideningType;
        }
        function checkAwaitExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 16384 /* AwaitContext */)) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function);
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var operandType = checkExpression(node.expression);
            return checkAwaitedType(operandType, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        function checkPrefixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            if (node.operand.kind === 8 /* NumericLiteral */) {
                if (node.operator === 38 /* MinusToken */) {
                    return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text));
                }
                else if (node.operator === 37 /* PlusToken */) {
                    return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text));
                }
            }
            switch (node.operator) {
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                case 52 /* TildeToken */:
                    checkNonNullType(operandType, node.operand);
                    if (maybeTypeOfKind(operandType, 512 /* ESSymbol */)) {
                        error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator));
                    }
                    return numberType;
                case 51 /* ExclamationToken */:
                    var facts = getTypeFacts(operandType) & (1048576 /* Truthy */ | 2097152 /* Falsy */);
                    return facts === 1048576 /* Truthy */ ? falseType :
                        facts === 2097152 /* Falsy */ ? trueType :
                            booleanType;
                case 43 /* PlusPlusToken */:
                case 44 /* MinusMinusToken */:
                    var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
                    if (ok) {
                        // run check only if former checks succeeded to avoid reporting cascading errors
                        checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
                    }
                    return numberType;
            }
            return unknownType;
        }
        function checkPostfixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
            if (ok) {
                // run check only if former checks succeeded to avoid reporting cascading errors
                checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
            }
            return numberType;
        }
        // Return true if type might be of the given kind. A union or intersection type might be of a given
        // kind if at least one constituent type is of the given kind.
        function maybeTypeOfKind(type, kind) {
            if (type.flags & kind) {
                return true;
            }
            if (type.flags & 196608 /* UnionOrIntersection */) {
                var types = type.types;
                for (var _i = 0, types_18 = types; _i < types_18.length; _i++) {
                    var t = types_18[_i];
                    if (maybeTypeOfKind(t, kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isTypeAssignableToKind(source, kind, strict) {
            if (source.flags & kind) {
                return true;
            }
            if (strict && source.flags & (1 /* Any */ | 1024 /* Void */ | 2048 /* Undefined */ | 4096 /* Null */)) {
                return false;
            }
            return (kind & 84 /* NumberLike */ && isTypeAssignableTo(source, numberType)) ||
                (kind & 262178 /* StringLike */ && isTypeAssignableTo(source, stringType)) ||
                (kind & 136 /* BooleanLike */ && isTypeAssignableTo(source, booleanType)) ||
                (kind & 1024 /* Void */ && isTypeAssignableTo(source, voidType)) ||
                (kind & 8192 /* Never */ && isTypeAssignableTo(source, neverType)) ||
                (kind & 4096 /* Null */ && isTypeAssignableTo(source, nullType)) ||
                (kind & 2048 /* Undefined */ && isTypeAssignableTo(source, undefinedType)) ||
                (kind & 512 /* ESSymbol */ && isTypeAssignableTo(source, esSymbolType)) ||
                (kind & 16777216 /* NonPrimitive */ && isTypeAssignableTo(source, nonPrimitiveType));
        }
        function isConstEnumObjectType(type) {
            return getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && isConstEnumSymbol(type.symbol);
        }
        function isConstEnumSymbol(symbol) {
            return (symbol.flags & 128 /* ConstEnum */) !== 0;
        }
        function checkInstanceOfExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            // TypeScript 1.0 spec (April 2014): 4.15.4
            // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
            // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature.
            // The result is always of the Boolean primitive type.
            // NOTE: do not raise error if leftType is unknown as related error was already reported
            if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190 /* Primitive */)) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            // NOTE: do not raise error if right is unknown as related error was already reported
            if (!(isTypeAny(rightType) ||
                getSignaturesOfType(rightType, 0 /* Call */).length ||
                getSignaturesOfType(rightType, 1 /* Construct */).length ||
                isTypeSubtypeOf(rightType, globalFunctionType))) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
            }
            return booleanType;
        }
        function checkInExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            leftType = checkNonNullType(leftType, left);
            rightType = checkNonNullType(rightType, right);
            // TypeScript 1.0 spec (April 2014): 4.15.5
            // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
            // and the right operand to be of type Any, an object type, or a type parameter type.
            // The result is always of the Boolean primitive type.
            if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 /* NumberLike */ | 512 /* ESSymbol */))) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
            }
            if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            return booleanType;
        }
        function checkObjectLiteralAssignment(node, sourceType) {
            var properties = node.properties;
            for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) {
                var p = properties_7[_i];
                checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
            }
            return sourceType;
        }
        /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
        function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType, property, allProperties) {
            if (property.kind === 261 /* PropertyAssignment */ || property.kind === 262 /* ShorthandPropertyAssignment */) {
                var name = property.name;
                if (name.kind === 144 /* ComputedPropertyName */) {
                    checkComputedPropertyName(name);
                }
                if (isComputedNonLiteralName(name)) {
                    return undefined;
                }
                var text = ts.getTextOfPropertyName(name);
                var type = isTypeAny(objectLiteralType)
                    ? objectLiteralType
                    : getTypeOfPropertyOfType(objectLiteralType, text) ||
                        isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, 1 /* Number */) ||
                        getIndexTypeOfType(objectLiteralType, 0 /* String */);
                if (type) {
                    if (property.kind === 262 /* ShorthandPropertyAssignment */) {
                        return checkDestructuringAssignment(property, type);
                    }
                    else {
                        // non-shorthand property assignments should always have initializers
                        return checkDestructuringAssignment(property.initializer, type);
                    }
                }
                else {
                    error(name, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), ts.declarationNameToString(name));
                }
            }
            else if (property.kind === 263 /* SpreadAssignment */) {
                if (languageVersion < 5 /* ESNext */) {
                    checkExternalEmitHelpers(property, 4 /* Rest */);
                }
                var nonRestNames = [];
                if (allProperties) {
                    for (var i = 0; i < allProperties.length - 1; i++) {
                        nonRestNames.push(allProperties[i].name);
                    }
                }
                var type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
                return checkDestructuringAssignment(property.expression, type);
            }
            else {
                error(property, ts.Diagnostics.Property_assignment_expected);
            }
        }
        function checkArrayLiteralAssignment(node, sourceType, checkMode) {
            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                checkExternalEmitHelpers(node, 512 /* Read */);
            }
            // This elementType will be used if the specific property corresponding to this index is not
            // present (aka the tuple element property). This call also checks that the parentType is in
            // fact an iterable or array (depending on target language).
            var elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType;
            var elements = node.elements;
            for (var i = 0; i < elements.length; i++) {
                checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
            }
            return sourceType;
        }
        function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, checkMode) {
            var elements = node.elements;
            var element = elements[elementIndex];
            if (element.kind !== 200 /* OmittedExpression */) {
                if (element.kind !== 198 /* SpreadElement */) {
                    var propName = "" + elementIndex;
                    var type = isTypeAny(sourceType)
                        ? sourceType
                        : isTupleLikeType(sourceType)
                            ? getTypeOfPropertyOfType(sourceType, propName)
                            : elementType;
                    if (type) {
                        return checkDestructuringAssignment(element, type, checkMode);
                    }
                    else {
                        // We still need to check element expression here because we may need to set appropriate flag on the expression
                        // such as NodeCheckFlags.LexicalThis on "this"expression.
                        checkExpression(element);
                        if (isTupleType(sourceType)) {
                            error(element, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(sourceType), elements.length);
                        }
                        else {
                            error(element, ts.Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
                        }
                    }
                }
                else {
                    if (elementIndex < elements.length - 1) {
                        error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                    }
                    else {
                        var restExpression = element.expression;
                        if (restExpression.kind === 194 /* BinaryExpression */ && restExpression.operatorToken.kind === 58 /* EqualsToken */) {
                            error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                        }
                        else {
                            return checkDestructuringAssignment(restExpression, createArrayType(elementType), checkMode);
                        }
                    }
                }
            }
            return undefined;
        }
        function checkDestructuringAssignment(exprOrAssignment, sourceType, checkMode) {
            var target;
            if (exprOrAssignment.kind === 262 /* ShorthandPropertyAssignment */) {
                var prop = exprOrAssignment;
                if (prop.objectAssignmentInitializer) {
                    // In strict null checking mode, if a default value of a non-undefined type is specified, remove
                    // undefined from the final type.
                    if (strictNullChecks &&
                        !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & 2048 /* Undefined */)) {
                        sourceType = getTypeWithFacts(sourceType, 131072 /* NEUndefined */);
                    }
                    checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode);
                }
                target = exprOrAssignment.name;
            }
            else {
                target = exprOrAssignment;
            }
            if (target.kind === 194 /* BinaryExpression */ && target.operatorToken.kind === 58 /* EqualsToken */) {
                checkBinaryExpression(target, checkMode);
                target = target.left;
            }
            if (target.kind === 178 /* ObjectLiteralExpression */) {
                return checkObjectLiteralAssignment(target, sourceType);
            }
            if (target.kind === 177 /* ArrayLiteralExpression */) {
                return checkArrayLiteralAssignment(target, sourceType, checkMode);
            }
            return checkReferenceAssignment(target, sourceType, checkMode);
        }
        function checkReferenceAssignment(target, sourceType, checkMode) {
            var targetType = checkExpression(target, checkMode);
            var error = target.parent.kind === 263 /* SpreadAssignment */ ?
                ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
            if (checkReferenceExpression(target, error)) {
                checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined);
            }
            return sourceType;
        }
        /**
         * This is a *shallow* check: An expression is side-effect-free if the
         * evaluation of the expression *itself* cannot produce side effects.
         * For example, x++ / 3 is side-effect free because the / operator
         * does not have side effects.
         * The intent is to "smell test" an expression for correctness in positions where
         * its value is discarded (e.g. the left side of the comma operator).
         */
        function isSideEffectFree(node) {
            node = ts.skipParentheses(node);
            switch (node.kind) {
                case 71 /* Identifier */:
                case 9 /* StringLiteral */:
                case 12 /* RegularExpressionLiteral */:
                case 183 /* TaggedTemplateExpression */:
                case 196 /* TemplateExpression */:
                case 13 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 101 /* TrueKeyword */:
                case 86 /* FalseKeyword */:
                case 95 /* NullKeyword */:
                case 139 /* UndefinedKeyword */:
                case 186 /* FunctionExpression */:
                case 199 /* ClassExpression */:
                case 187 /* ArrowFunction */:
                case 177 /* ArrayLiteralExpression */:
                case 178 /* ObjectLiteralExpression */:
                case 189 /* TypeOfExpression */:
                case 203 /* NonNullExpression */:
                case 250 /* JsxSelfClosingElement */:
                case 249 /* JsxElement */:
                    return true;
                case 195 /* ConditionalExpression */:
                    return isSideEffectFree(node.whenTrue) &&
                        isSideEffectFree(node.whenFalse);
                case 194 /* BinaryExpression */:
                    if (ts.isAssignmentOperator(node.operatorToken.kind)) {
                        return false;
                    }
                    return isSideEffectFree(node.left) &&
                        isSideEffectFree(node.right);
                case 192 /* PrefixUnaryExpression */:
                case 193 /* PostfixUnaryExpression */:
                    // Unary operators ~, !, +, and - have no side effects.
                    // The rest do.
                    switch (node.operator) {
                        case 51 /* ExclamationToken */:
                        case 37 /* PlusToken */:
                        case 38 /* MinusToken */:
                        case 52 /* TildeToken */:
                            return true;
                    }
                    return false;
                // Some forms listed here for clarity
                case 190 /* VoidExpression */: // Explicit opt-out
                case 184 /* TypeAssertionExpression */: // Not SEF, but can produce useful type warnings
                case 202 /* AsExpression */: // Not SEF, but can produce useful type warnings
                default:
                    return false;
            }
        }
        function isTypeEqualityComparableTo(source, target) {
            return (target.flags & 6144 /* Nullable */) !== 0 || isTypeComparableTo(source, target);
        }
        function getBestChoiceType(type1, type2) {
            var firstAssignableToSecond = isTypeAssignableTo(type1, type2);
            var secondAssignableToFirst = isTypeAssignableTo(type2, type1);
            return secondAssignableToFirst && !firstAssignableToSecond ? type1 :
                firstAssignableToSecond && !secondAssignableToFirst ? type2 :
                    getUnionType([type1, type2], /*subtypeReduction*/ true);
        }
        function checkBinaryExpression(node, checkMode) {
            return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
        }
        function checkBinaryLikeExpression(left, operatorToken, right, checkMode, errorNode) {
            var operator = operatorToken.kind;
            if (operator === 58 /* EqualsToken */ && (left.kind === 178 /* ObjectLiteralExpression */ || left.kind === 177 /* ArrayLiteralExpression */)) {
                return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode);
            }
            var leftType = checkExpression(left, checkMode);
            var rightType = checkExpression(right, checkMode);
            switch (operator) {
                case 39 /* AsteriskToken */:
                case 40 /* AsteriskAsteriskToken */:
                case 61 /* AsteriskEqualsToken */:
                case 62 /* AsteriskAsteriskEqualsToken */:
                case 41 /* SlashToken */:
                case 63 /* SlashEqualsToken */:
                case 42 /* PercentToken */:
                case 64 /* PercentEqualsToken */:
                case 38 /* MinusToken */:
                case 60 /* MinusEqualsToken */:
                case 45 /* LessThanLessThanToken */:
                case 65 /* LessThanLessThanEqualsToken */:
                case 46 /* GreaterThanGreaterThanToken */:
                case 66 /* GreaterThanGreaterThanEqualsToken */:
                case 47 /* GreaterThanGreaterThanGreaterThanToken */:
                case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 49 /* BarToken */:
                case 69 /* BarEqualsToken */:
                case 50 /* CaretToken */:
                case 70 /* CaretEqualsToken */:
                case 48 /* AmpersandToken */:
                case 68 /* AmpersandEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    leftType = checkNonNullType(leftType, left);
                    rightType = checkNonNullType(rightType, right);
                    var suggestedOperator = void 0;
                    // if a user tries to apply a bitwise operator to 2 boolean operands
                    // try and return them a helpful suggestion
                    if ((leftType.flags & 136 /* BooleanLike */) &&
                        (rightType.flags & 136 /* BooleanLike */) &&
                        (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
                        error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator));
                    }
                    else {
                        // otherwise just check each operand separately and report errors as normal
                        var leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
                        var rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
                        if (leftOk && rightOk) {
                            checkAssignmentOperator(numberType);
                        }
                    }
                    return numberType;
                case 37 /* PlusToken */:
                case 59 /* PlusEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    if (!isTypeAssignableToKind(leftType, 262178 /* StringLike */) && !isTypeAssignableToKind(rightType, 262178 /* StringLike */)) {
                        leftType = checkNonNullType(leftType, left);
                        rightType = checkNonNullType(rightType, right);
                    }
                    var resultType = void 0;
                    if (isTypeAssignableToKind(leftType, 84 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 84 /* NumberLike */, /*strict*/ true)) {
                        // Operands of an enum type are treated as having the primitive type Number.
                        // If both operands are of the Number primitive type, the result is of the Number primitive type.
                        resultType = numberType;
                    }
                    else if (isTypeAssignableToKind(leftType, 262178 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 262178 /* StringLike */, /*strict*/ true)) {
                        // If one or both operands are of the String primitive type, the result is of the String primitive type.
                        resultType = stringType;
                    }
                    else if (isTypeAny(leftType) || isTypeAny(rightType)) {
                        // Otherwise, the result is of type Any.
                        // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
                        resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType;
                    }
                    // Symbols are not allowed at all in arithmetic expressions
                    if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
                        return resultType;
                    }
                    if (!resultType) {
                        reportOperatorError();
                        return anyType;
                    }
                    if (operator === 59 /* PlusEqualsToken */) {
                        checkAssignmentOperator(resultType);
                    }
                    return resultType;
                case 27 /* LessThanToken */:
                case 29 /* GreaterThanToken */:
                case 30 /* LessThanEqualsToken */:
                case 31 /* GreaterThanEqualsToken */:
                    if (checkForDisallowedESSymbolOperand(operator)) {
                        leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
                        rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
                        if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
                            reportOperatorError();
                        }
                    }
                    return booleanType;
                case 32 /* EqualsEqualsToken */:
                case 33 /* ExclamationEqualsToken */:
                case 34 /* EqualsEqualsEqualsToken */:
                case 35 /* ExclamationEqualsEqualsToken */:
                    var leftIsLiteral = isLiteralType(leftType);
                    var rightIsLiteral = isLiteralType(rightType);
                    if (!leftIsLiteral || !rightIsLiteral) {
                        leftType = leftIsLiteral ? getBaseTypeOfLiteralType(leftType) : leftType;
                        rightType = rightIsLiteral ? getBaseTypeOfLiteralType(rightType) : rightType;
                    }
                    if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
                        reportOperatorError();
                    }
                    return booleanType;
                case 93 /* InstanceOfKeyword */:
                    return checkInstanceOfExpression(left, right, leftType, rightType);
                case 92 /* InKeyword */:
                    return checkInExpression(left, right, leftType, rightType);
                case 53 /* AmpersandAmpersandToken */:
                    return getTypeFacts(leftType) & 1048576 /* Truthy */ ?
                        getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
                        leftType;
                case 54 /* BarBarToken */:
                    return getTypeFacts(leftType) & 2097152 /* Falsy */ ?
                        getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) :
                        leftType;
                case 58 /* EqualsToken */:
                    checkAssignmentOperator(rightType);
                    return getRegularTypeOfObjectLiteral(rightType);
                case 26 /* CommaToken */:
                    if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) {
                        error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects);
                    }
                    return rightType;
            }
            function isEvalNode(node) {
                return node.kind === 71 /* Identifier */ && node.escapedText === "eval";
            }
            // Return true if there was no error, false if there was an error.
            function checkForDisallowedESSymbolOperand(operator) {
                var offendingSymbolOperand = maybeTypeOfKind(leftType, 512 /* ESSymbol */) ? left :
                    maybeTypeOfKind(rightType, 512 /* ESSymbol */) ? right :
                        undefined;
                if (offendingSymbolOperand) {
                    error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator));
                    return false;
                }
                return true;
            }
            function getSuggestedBooleanOperator(operator) {
                switch (operator) {
                    case 49 /* BarToken */:
                    case 69 /* BarEqualsToken */:
                        return 54 /* BarBarToken */;
                    case 50 /* CaretToken */:
                    case 70 /* CaretEqualsToken */:
                        return 35 /* ExclamationEqualsEqualsToken */;
                    case 48 /* AmpersandToken */:
                    case 68 /* AmpersandEqualsToken */:
                        return 53 /* AmpersandAmpersandToken */;
                    default:
                        return undefined;
                }
            }
            function checkAssignmentOperator(valueType) {
                if (produceDiagnostics && ts.isAssignmentOperator(operator)) {
                    // TypeScript 1.0 spec (April 2014): 4.17
                    // An assignment of the form
                    //    VarExpr = ValueExpr
                    // requires VarExpr to be classified as a reference
                    // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
                    // and the type of the non - compound operation to be assignable to the type of VarExpr.
                    if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)) {
                        // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
                        checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ undefined);
                    }
                }
            }
            function reportOperatorError() {
                error(errorNode || operatorToken, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), typeToString(leftType), typeToString(rightType));
            }
        }
        function isYieldExpressionInClass(node) {
            var current = node;
            var parent = node.parent;
            while (parent) {
                if (ts.isFunctionLike(parent) && current === parent.body) {
                    return false;
                }
                else if (ts.isClassLike(current)) {
                    return true;
                }
                current = parent;
                parent = parent.parent;
            }
            return false;
        }
        function checkYieldExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 4096 /* YieldContext */) || isYieldExpressionInClass(node)) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            if (node.expression) {
                var func = ts.getContainingFunction(node);
                // If the user's code is syntactically correct, the func should always have a star. After all,
                // we are in a yield context.
                var functionFlags = func && ts.getFunctionFlags(func);
                if (node.asteriskToken) {
                    // Async generator functions prior to ESNext require the __await, __asyncDelegator,
                    // and __asyncValues helpers
                    if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ &&
                        languageVersion < 5 /* ESNext */) {
                        checkExternalEmitHelpers(node, 26624 /* AsyncDelegatorIncludes */);
                    }
                    // Generator functions prior to ES2015 require the __values helper
                    if ((functionFlags & 3 /* AsyncGenerator */) === 1 /* Generator */ &&
                        languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                        checkExternalEmitHelpers(node, 256 /* Values */);
                    }
                }
                if (functionFlags & 1 /* Generator */) {
                    var expressionType = checkExpressionCached(node.expression);
                    var expressionElementType = void 0;
                    var nodeIsYieldStar = !!node.asteriskToken;
                    if (nodeIsYieldStar) {
                        expressionElementType = checkIteratedTypeOrElementType(expressionType, node.expression, /*allowStringInput*/ false, (functionFlags & 2 /* Async */) !== 0);
                    }
                    // There is no point in doing an assignability check if the function
                    // has no explicit return type because the return type is directly computed
                    // from the yield expressions.
                    var returnType = ts.getEffectiveReturnTypeNode(func);
                    if (returnType) {
                        var signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & 2 /* Async */) !== 0) || anyType;
                        if (nodeIsYieldStar) {
                            checkTypeAssignableTo(functionFlags & 2 /* Async */
                                ? getAwaitedType(expressionElementType, node.expression, ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
                                : expressionElementType, signatureElementType, node.expression, 
                            /*headMessage*/ undefined);
                        }
                        else {
                            checkTypeAssignableTo(functionFlags & 2 /* Async */
                                ? getAwaitedType(expressionType, node.expression, ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
                                : expressionType, signatureElementType, node.expression, 
                            /*headMessage*/ undefined);
                        }
                    }
                }
            }
            // Both yield and yield* expressions have type 'any'
            return anyType;
        }
        function checkConditionalExpression(node, checkMode) {
            checkExpression(node.condition);
            var type1 = checkExpression(node.whenTrue, checkMode);
            var type2 = checkExpression(node.whenFalse, checkMode);
            return getBestChoiceType(type1, type2);
        }
        function checkTemplateExpression(node) {
            // We just want to check each expressions, but we are unconcerned with
            // the type of each expression, as any value may be coerced into a string.
            // It is worth asking whether this is what we really want though.
            // A place where we actually *are* concerned with the expressions' types are
            // in tagged templates.
            ts.forEach(node.templateSpans, function (templateSpan) {
                checkExpression(templateSpan.expression);
            });
            return stringType;
        }
        function checkExpressionWithContextualType(node, contextualType, contextualMapper) {
            var saveContextualType = node.contextualType;
            var saveContextualMapper = node.contextualMapper;
            node.contextualType = contextualType;
            node.contextualMapper = contextualMapper;
            var checkMode = contextualMapper === identityMapper ? 1 /* SkipContextSensitive */ :
                contextualMapper ? 2 /* Inferential */ : 0 /* Normal */;
            var result = checkExpression(node, checkMode);
            node.contextualType = saveContextualType;
            node.contextualMapper = saveContextualMapper;
            return result;
        }
        function checkExpressionCached(node, checkMode) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // When computing a type that we're going to cache, we need to ignore any ongoing control flow
                // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart
                // to the top of the stack ensures all transient types are computed from a known point.
                var saveFlowLoopStart = flowLoopStart;
                flowLoopStart = flowLoopCount;
                links.resolvedType = checkExpression(node, checkMode);
                flowLoopStart = saveFlowLoopStart;
            }
            return links.resolvedType;
        }
        function isTypeAssertion(node) {
            node = ts.skipParentheses(node);
            return node.kind === 184 /* TypeAssertionExpression */ || node.kind === 202 /* AsExpression */;
        }
        function checkDeclarationInitializer(declaration) {
            var type = getTypeOfExpression(declaration.initializer, /*cache*/ true);
            return ts.getCombinedNodeFlags(declaration) & 2 /* Const */ ||
                ts.getCombinedModifierFlags(declaration) & 64 /* Readonly */ && !ts.isParameterPropertyDeclaration(declaration) ||
                isTypeAssertion(declaration.initializer) ? type : getWidenedLiteralType(type);
        }
        function isLiteralContextualType(contextualType) {
            if (contextualType) {
                if (contextualType.flags & 540672 /* TypeVariable */) {
                    var constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
                    // If the type parameter is constrained to the base primitive type we're checking for,
                    // consider this a literal context. For example, given a type parameter 'T extends string',
                    // this causes us to infer string literal types for T.
                    if (constraint.flags & (2 /* String */ | 4 /* Number */ | 8 /* Boolean */ | 16 /* Enum */)) {
                        return true;
                    }
                    contextualType = constraint;
                }
                return maybeTypeOfKind(contextualType, (224 /* Literal */ | 262144 /* Index */));
            }
            return false;
        }
        function checkExpressionForMutableLocation(node, checkMode, contextualType) {
            if (arguments.length === 2) {
                contextualType = getContextualType(node);
            }
            var type = checkExpression(node, checkMode);
            var shouldWiden = isTypeAssertion(node) || isLiteralContextualType(contextualType);
            return shouldWiden ? type : getWidenedLiteralType(type);
        }
        function checkPropertyAssignment(node, checkMode) {
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 144 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            return checkExpressionForMutableLocation(node.initializer, checkMode);
        }
        function checkObjectLiteralMethod(node, checkMode) {
            // Grammar checking
            checkGrammarMethod(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 144 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
            return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
        }
        function instantiateTypeWithSingleGenericCallSignature(node, type, checkMode) {
            if (checkMode === 2 /* Inferential */) {
                var signature = getSingleCallSignature(type);
                if (signature && signature.typeParameters) {
                    var contextualType = getApparentTypeOfContextualType(node);
                    if (contextualType) {
                        var contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
                        if (contextualSignature && !contextualSignature.typeParameters) {
                            return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
                        }
                    }
                }
            }
            return type;
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         * A cache argument of true indicates that if the function performs a full type check, it is ok
         * to cache the result.
         */
        function getTypeOfExpression(node, cache) {
            // Optimize for the common case of a call to a function with a single non-generic call
            // signature where we can just fetch the return type without checking the arguments.
            if (node.kind === 181 /* CallExpression */ && node.expression.kind !== 97 /* SuperKeyword */ && !ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
                var funcType = checkNonNullExpression(node.expression);
                var signature = getSingleCallSignature(funcType);
                if (signature && !signature.typeParameters) {
                    return getReturnTypeOfSignature(signature);
                }
            }
            // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
            // should have a parameter that indicates whether full error checking is required such that
            // we can perform the optimizations locally.
            return cache ? checkExpressionCached(node) : checkExpression(node);
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         * It is intended for uses where you know there is no contextual type,
         * and requesting the contextual type might cause a circularity or other bad behaviour.
         * It sets the contextual type of the node to any before calling getTypeOfExpression.
         */
        function getContextFreeTypeOfExpression(node) {
            var saveContextualType = node.contextualType;
            node.contextualType = anyType;
            var type = getTypeOfExpression(node);
            node.contextualType = saveContextualType;
            return type;
        }
        // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When
        // contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the
        // expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in
        // conjunction with the generic contextual type. When contextualMapper is equal to the identityMapper function
        // object, it serves as an indicator that all contained function and arrow expressions should be considered to
        // have the wildcard function type; this form of type check is used during overload resolution to exclude
        // contextually typed function and arrow expressions in the initial phase.
        function checkExpression(node, checkMode) {
            var type;
            if (node.kind === 143 /* QualifiedName */) {
                type = checkQualifiedName(node);
            }
            else {
                var uninstantiatedType = checkExpressionWorker(node, checkMode);
                type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
            }
            if (isConstEnumObjectType(type)) {
                // enum object type for const enums are only permitted in:
                // - 'left' in property access
                // - 'object' in indexed access
                // - target in rhs of import statement
                var ok = (node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.expression === node) ||
                    (node.parent.kind === 180 /* ElementAccessExpression */ && node.parent.expression === node) ||
                    ((node.kind === 71 /* Identifier */ || node.kind === 143 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node));
                if (!ok) {
                    error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment);
                }
            }
            return type;
        }
        function checkParenthesizedExpression(node, checkMode) {
            var tag = ts.isInJavaScriptFile(node) ? ts.getJSDocTypeTag(node) : undefined;
            if (tag) {
                return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
            }
            return checkExpression(node.expression, checkMode);
        }
        function checkExpressionWorker(node, checkMode) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return checkIdentifier(node);
                case 99 /* ThisKeyword */:
                    return checkThisExpression(node);
                case 97 /* SuperKeyword */:
                    return checkSuperExpression(node);
                case 95 /* NullKeyword */:
                    return nullWideningType;
                case 13 /* NoSubstitutionTemplateLiteral */:
                case 9 /* StringLiteral */:
                    return getFreshTypeOfLiteralType(getLiteralType(node.text));
                case 8 /* NumericLiteral */:
                    checkGrammarNumericLiteral(node);
                    return getFreshTypeOfLiteralType(getLiteralType(+node.text));
                case 101 /* TrueKeyword */:
                    return trueType;
                case 86 /* FalseKeyword */:
                    return falseType;
                case 196 /* TemplateExpression */:
                    return checkTemplateExpression(node);
                case 12 /* RegularExpressionLiteral */:
                    return globalRegExpType;
                case 177 /* ArrayLiteralExpression */:
                    return checkArrayLiteral(node, checkMode);
                case 178 /* ObjectLiteralExpression */:
                    return checkObjectLiteral(node, checkMode);
                case 179 /* PropertyAccessExpression */:
                    return checkPropertyAccessExpression(node);
                case 180 /* ElementAccessExpression */:
                    return checkIndexedAccess(node);
                case 181 /* CallExpression */:
                    if (node.expression.kind === 91 /* ImportKeyword */) {
                        return checkImportCallExpression(node);
                    }
                /* falls through */
                case 182 /* NewExpression */:
                    return checkCallExpression(node);
                case 183 /* TaggedTemplateExpression */:
                    return checkTaggedTemplateExpression(node);
                case 185 /* ParenthesizedExpression */:
                    return checkParenthesizedExpression(node, checkMode);
                case 199 /* ClassExpression */:
                    return checkClassExpression(node);
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
                case 189 /* TypeOfExpression */:
                    return checkTypeOfExpression(node);
                case 184 /* TypeAssertionExpression */:
                case 202 /* AsExpression */:
                    return checkAssertion(node);
                case 203 /* NonNullExpression */:
                    return checkNonNullAssertion(node);
                case 204 /* MetaProperty */:
                    return checkMetaProperty(node);
                case 188 /* DeleteExpression */:
                    return checkDeleteExpression(node);
                case 190 /* VoidExpression */:
                    return checkVoidExpression(node);
                case 191 /* AwaitExpression */:
                    return checkAwaitExpression(node);
                case 192 /* PrefixUnaryExpression */:
                    return checkPrefixUnaryExpression(node);
                case 193 /* PostfixUnaryExpression */:
                    return checkPostfixUnaryExpression(node);
                case 194 /* BinaryExpression */:
                    return checkBinaryExpression(node, checkMode);
                case 195 /* ConditionalExpression */:
                    return checkConditionalExpression(node, checkMode);
                case 198 /* SpreadElement */:
                    return checkSpreadExpression(node, checkMode);
                case 200 /* OmittedExpression */:
                    return undefinedWideningType;
                case 197 /* YieldExpression */:
                    return checkYieldExpression(node);
                case 256 /* JsxExpression */:
                    return checkJsxExpression(node, checkMode);
                case 249 /* JsxElement */:
                    return checkJsxElement(node);
                case 250 /* JsxSelfClosingElement */:
                    return checkJsxSelfClosingElement(node);
                case 254 /* JsxAttributes */:
                    return checkJsxAttributes(node, checkMode);
                case 251 /* JsxOpeningElement */:
                    ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
            }
            return unknownType;
        }
        // DECLARATION AND STATEMENT TYPE CHECKING
        function checkTypeParameter(node) {
            // Grammar Checking
            if (node.expression) {
                grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
            }
            checkSourceElement(node.constraint);
            checkSourceElement(node.default);
            var typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
            if (!hasNonCircularBaseConstraint(typeParameter)) {
                error(node.constraint, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
            }
            if (!hasNonCircularTypeParameterDefault(typeParameter)) {
                error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
            }
            var constraintType = getConstraintOfTypeParameter(typeParameter);
            var defaultType = getDefaultFromTypeParameter(typeParameter);
            if (constraintType && defaultType) {
                checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
            }
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
            }
        }
        function checkParameter(node) {
            // Grammar checking
            // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
            // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
            // or if its FunctionBody is strict code(11.1.5).
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node);
            checkVariableLikeDeclaration(node);
            var func = ts.getContainingFunction(node);
            if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                if (!(func.kind === 152 /* Constructor */ && ts.nodeIsPresent(func.body))) {
                    error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
                }
            }
            if (node.questionToken && ts.isBindingPattern(node.name) && func.body) {
                error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
            }
            if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) {
                if (ts.indexOf(func.parameters, node) !== 0) {
                    error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText);
                }
                if (func.kind === 152 /* Constructor */ || func.kind === 156 /* ConstructSignature */ || func.kind === 161 /* ConstructorType */) {
                    error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter);
                }
            }
            // Only check rest parameter type if it's not a binding pattern. Since binding patterns are
            // not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
            if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isArrayType(getTypeOfSymbol(node.symbol))) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type);
            }
        }
        function getTypePredicateParameterIndex(parameterList, parameter) {
            if (parameterList) {
                for (var i = 0; i < parameterList.length; i++) {
                    var param = parameterList[i];
                    if (param.name.kind === 71 /* Identifier */ && param.name.escapedText === parameter.escapedText) {
                        return i;
                    }
                }
            }
            return -1;
        }
        function checkTypePredicate(node) {
            var parent = getTypePredicateParent(node);
            if (!parent) {
                // The parent must not be valid.
                error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
                return;
            }
            var typePredicate = getSignatureFromDeclaration(parent).typePredicate;
            if (!typePredicate) {
                return;
            }
            checkSourceElement(node.type);
            var parameterName = node.parameterName;
            if (ts.isThisTypePredicate(typePredicate)) {
                getTypeFromThisTypeNode(parameterName);
            }
            else {
                if (typePredicate.parameterIndex >= 0) {
                    if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) {
                        error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
                    }
                    else {
                        var leadingError = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type);
                        checkTypeAssignableTo(typePredicate.type, getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), node.type, 
                        /*headMessage*/ undefined, leadingError);
                    }
                }
                else if (parameterName) {
                    var hasReportedError = false;
                    for (var _i = 0, _a = parent.parameters; _i < _a.length; _i++) {
                        var name = _a[_i].name;
                        if (ts.isBindingPattern(name) &&
                            checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) {
                            hasReportedError = true;
                            break;
                        }
                    }
                    if (!hasReportedError) {
                        error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName);
                    }
                }
            }
        }
        function getTypePredicateParent(node) {
            switch (node.parent.kind) {
                case 187 /* ArrowFunction */:
                case 155 /* CallSignature */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 160 /* FunctionType */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                    var parent = node.parent;
                    if (node === parent.type) {
                        return parent;
                    }
            }
        }
        function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (ts.isOmittedExpression(element)) {
                    continue;
                }
                var name = element.name;
                if (name.kind === 71 /* Identifier */ && name.escapedText === predicateVariableName) {
                    error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName);
                    return true;
                }
                else if (name.kind === 175 /* ArrayBindingPattern */ || name.kind === 174 /* ObjectBindingPattern */) {
                    if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) {
                        return true;
                    }
                }
            }
        }
        function checkSignatureDeclaration(node) {
            // Grammar checking
            if (node.kind === 157 /* IndexSignature */) {
                checkGrammarIndexSignature(node);
            }
            else if (node.kind === 160 /* FunctionType */ || node.kind === 228 /* FunctionDeclaration */ || node.kind === 161 /* ConstructorType */ ||
                node.kind === 155 /* CallSignature */ || node.kind === 152 /* Constructor */ ||
                node.kind === 156 /* ConstructSignature */) {
                checkGrammarFunctionLikeDeclaration(node);
            }
            var functionFlags = ts.getFunctionFlags(node);
            if (!(functionFlags & 4 /* Invalid */)) {
                // Async generators prior to ESNext require the __await and __asyncGenerator helpers
                if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 5 /* ESNext */) {
                    checkExternalEmitHelpers(node, 6144 /* AsyncGeneratorIncludes */);
                }
                // Async functions prior to ES2017 require the __awaiter helper
                if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ && languageVersion < 4 /* ES2017 */) {
                    checkExternalEmitHelpers(node, 64 /* Awaiter */);
                }
                // Generator functions, Async functions, and Async Generator functions prior to
                // ES2015 require the __generator helper
                if ((functionFlags & 3 /* AsyncGenerator */) !== 0 /* Normal */ && languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(node, 128 /* Generator */);
                }
            }
            checkTypeParameters(node.typeParameters);
            ts.forEach(node.parameters, checkParameter);
            // TODO(rbuckton): Should we start checking JSDoc types?
            if (node.type) {
                checkSourceElement(node.type);
            }
            if (produceDiagnostics) {
                checkCollisionWithArgumentsInGeneratedCode(node);
                var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
                if (noImplicitAny && !returnTypeNode) {
                    switch (node.kind) {
                        case 156 /* ConstructSignature */:
                            error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                        case 155 /* CallSignature */:
                            error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                    }
                }
                if (returnTypeNode) {
                    var functionFlags_1 = ts.getFunctionFlags(node);
                    if ((functionFlags_1 & (4 /* Invalid */ | 1 /* Generator */)) === 1 /* Generator */) {
                        var returnType = getTypeFromTypeNode(returnTypeNode);
                        if (returnType === voidType) {
                            error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation);
                        }
                        else {
                            var generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags_1 & 2 /* Async */) !== 0) || anyType;
                            var iterableIteratorInstantiation = functionFlags_1 & 2 /* Async */
                                ? createAsyncIterableIteratorType(generatorElementType) // AsyncGenerator function
                                : createIterableIteratorType(generatorElementType); // Generator function
                            // Naively, one could check that IterableIterator<any> is assignable to the return type annotation.
                            // However, that would not catch the error in the following case.
                            //
                            //    interface BadGenerator extends Iterable<number>, Iterator<string> { }
                            //    function* g(): BadGenerator { } // Iterable and Iterator have different types!
                            //
                            checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode);
                        }
                    }
                    else if ((functionFlags_1 & 3 /* AsyncGenerator */) === 2 /* Async */) {
                        checkAsyncFunctionReturnType(node);
                    }
                }
                if (noUnusedIdentifiers && !node.body) {
                    checkUnusedTypeParameters(node);
                }
            }
        }
        function checkClassForDuplicateDeclarations(node) {
            var Declaration;
            (function (Declaration) {
                Declaration[Declaration["Getter"] = 1] = "Getter";
                Declaration[Declaration["Setter"] = 2] = "Setter";
                Declaration[Declaration["Method"] = 4] = "Method";
                Declaration[Declaration["Property"] = 3] = "Property";
            })(Declaration || (Declaration = {}));
            var instanceNames = ts.createUnderscoreEscapedMap();
            var staticNames = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 152 /* Constructor */) {
                    for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                        var param = _c[_b];
                        if (ts.isParameterPropertyDeclaration(param) && !ts.isBindingPattern(param.name)) {
                            addName(instanceNames, param.name, param.name.escapedText, 3 /* Property */);
                        }
                    }
                }
                else {
                    var isStatic = ts.hasModifier(member, 32 /* Static */);
                    var names = isStatic ? staticNames : instanceNames;
                    var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name);
                    if (memberName) {
                        switch (member.kind) {
                            case 153 /* GetAccessor */:
                                addName(names, member.name, memberName, 1 /* Getter */);
                                break;
                            case 154 /* SetAccessor */:
                                addName(names, member.name, memberName, 2 /* Setter */);
                                break;
                            case 149 /* PropertyDeclaration */:
                                addName(names, member.name, memberName, 3 /* Property */);
                                break;
                            case 151 /* MethodDeclaration */:
                                addName(names, member.name, memberName, 4 /* Method */);
                                break;
                        }
                    }
                }
            }
            function addName(names, location, name, meaning) {
                var prev = names.get(name);
                if (prev) {
                    if (prev & 4 /* Method */) {
                        if (meaning !== 4 /* Method */) {
                            error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                        }
                    }
                    else if (prev & meaning) {
                        error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                    }
                    else {
                        names.set(name, prev | meaning);
                    }
                }
                else {
                    names.set(name, meaning);
                }
            }
        }
        /**
         * Static members being set on a constructor function may conflict with built-in properties
         * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
         * built-in properties. This check issues a transpile error when a class has a static
         * member with the same name as a non-writable built-in property.
         *
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances
         */
        function checkClassForStaticPropertyNameConflicts(node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                var memberNameNode = member.name;
                var isStatic = ts.hasModifier(member, 32 /* Static */);
                if (isStatic && memberNameNode) {
                    var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode);
                    switch (memberName) {
                        case "name":
                        case "length":
                        case "caller":
                        case "arguments":
                        case "prototype":
                            var message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1;
                            var className = getNameOfSymbol(getSymbolOfNode(node));
                            error(memberNameNode, message, memberName, className);
                            break;
                    }
                }
            }
        }
        function checkObjectTypeForDuplicateDeclarations(node) {
            var names = ts.createMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 148 /* PropertySignature */) {
                    var memberName = void 0;
                    switch (member.name.kind) {
                        case 9 /* StringLiteral */:
                        case 8 /* NumericLiteral */:
                            memberName = member.name.text;
                            break;
                        case 71 /* Identifier */:
                            memberName = ts.idText(member.name);
                            break;
                        default:
                            continue;
                    }
                    if (names.get(memberName)) {
                        error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName);
                        error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
                    }
                    else {
                        names.set(memberName, true);
                    }
                }
            }
        }
        function checkTypeForDuplicateIndexSignatures(node) {
            if (node.kind === 230 /* InterfaceDeclaration */) {
                var nodeSymbol = getSymbolOfNode(node);
                // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration
                // to prevent this run check only for the first declaration of a given kind
                if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) {
                    return;
                }
            }
            // TypeScript 1.0 spec (April 2014)
            // 3.7.4: An object type can contain at most one string index signature and one numeric index signature.
            // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration
            var indexSymbol = getIndexSymbol(getSymbolOfNode(node));
            if (indexSymbol) {
                var seenNumericIndexer = false;
                var seenStringIndexer = false;
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var declaration = decl;
                    if (declaration.parameters.length === 1 && declaration.parameters[0].type) {
                        switch (declaration.parameters[0].type.kind) {
                            case 136 /* StringKeyword */:
                                if (!seenStringIndexer) {
                                    seenStringIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
                                }
                                break;
                            case 133 /* NumberKeyword */:
                                if (!seenNumericIndexer) {
                                    seenNumericIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_number_index_signature);
                                }
                                break;
                        }
                    }
                }
            }
        }
        function checkPropertyDeclaration(node) {
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
            checkVariableLikeDeclaration(node);
        }
        function checkMethodDeclaration(node) {
            // Grammar checking
            checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name);
            // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
            checkFunctionOrMethodDeclaration(node);
            // Abstract methods cannot have an implementation.
            // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
            if (ts.hasModifier(node, 128 /* Abstract */) && node.body) {
                error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name));
            }
        }
        function checkConstructorDeclaration(node) {
            // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
            checkSignatureDeclaration(node);
            // Grammar check for checking only related to constructorDeclaration
            checkGrammarConstructorTypeParameters(node) || checkGrammarConstructorTypeAnnotation(node);
            checkSourceElement(node.body);
            registerForUnusedIdentifiersCheck(node);
            var symbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind);
            // Only type check the symbol once
            if (node === firstDeclaration) {
                checkFunctionOrConstructorSymbol(symbol);
            }
            // exit early in the case of signature - super checks are not relevant to them
            if (ts.nodeIsMissing(node.body)) {
                return;
            }
            if (!produceDiagnostics) {
                return;
            }
            function containsSuperCallAsComputedPropertyName(n) {
                var name = ts.getNameOfDeclaration(n);
                return name && containsSuperCall(name);
            }
            function containsSuperCall(n) {
                if (ts.isSuperCall(n)) {
                    return true;
                }
                else if (ts.isFunctionLike(n)) {
                    return false;
                }
                else if (ts.isClassLike(n)) {
                    return ts.forEach(n.members, containsSuperCallAsComputedPropertyName);
                }
                return ts.forEachChild(n, containsSuperCall);
            }
            function isInstancePropertyWithInitializer(n) {
                return n.kind === 149 /* PropertyDeclaration */ &&
                    !ts.hasModifier(n, 32 /* Static */) &&
                    !!n.initializer;
            }
            // TS 1.0 spec (April 2014): 8.3.2
            // Constructors of classes with no extends clause may not contain super calls, whereas
            // constructors of derived classes must contain at least one super call somewhere in their function body.
            var containingClassDecl = node.parent;
            if (ts.getClassExtendsHeritageClauseElement(containingClassDecl)) {
                captureLexicalThis(node.parent, containingClassDecl);
                var classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
                var superCall = getSuperCallInConstructor(node);
                if (superCall) {
                    if (classExtendsNull) {
                        error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
                    }
                    // The first statement in the body of a constructor (excluding prologue directives) must be a super call
                    // if both of the following are true:
                    // - The containing class is a derived class.
                    // - The constructor declares parameter properties
                    //   or the containing class declares instance member variables with initializers.
                    var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) ||
                        ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); });
                    // Skip past any prologue directives to find the first statement
                    // to ensure that it was a super call.
                    if (superCallShouldBeFirst) {
                        var statements = node.body.statements;
                        var superCallStatement = void 0;
                        for (var _i = 0, statements_2 = statements; _i < statements_2.length; _i++) {
                            var statement = statements_2[_i];
                            if (statement.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
                                superCallStatement = statement;
                                break;
                            }
                            if (!ts.isPrologueDirective(statement)) {
                                break;
                            }
                        }
                        if (!superCallStatement) {
                            error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
                        }
                    }
                }
                else if (!classExtendsNull) {
                    error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
                }
            }
        }
        function checkAccessorDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking accessors
                checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
                checkDecorators(node);
                checkSignatureDeclaration(node);
                if (node.kind === 153 /* GetAccessor */) {
                    if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 128 /* HasImplicitReturn */)) {
                        if (!(node.flags & 256 /* HasExplicitReturn */)) {
                            error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value);
                        }
                    }
                }
                // Do not use hasDynamicName here, because that returns false for well known symbols.
                // We want to perform checkComputedPropertyName for all computed properties, including
                // well known symbols.
                if (node.name.kind === 144 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.name);
                }
                if (!ts.hasDynamicName(node)) {
                    // TypeScript 1.0 spec (April 2014): 8.4.3
                    // Accessors for the same member name must specify the same accessibility.
                    var otherKind = node.kind === 153 /* GetAccessor */ ? 154 /* SetAccessor */ : 153 /* GetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind);
                    if (otherAccessor) {
                        var nodeFlags = ts.getModifierFlags(node);
                        var otherFlags = ts.getModifierFlags(otherAccessor);
                        if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) {
                            error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
                        }
                        if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) {
                            error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
                        }
                        // TypeScript 1.0 spec (April 2014): 4.5
                        // If both accessors include type annotations, the specified types must be identical.
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type);
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
                    }
                }
                var returnType = getTypeOfAccessors(getSymbolOfNode(node));
                if (node.kind === 153 /* GetAccessor */) {
                    checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
                }
            }
            checkSourceElement(node.body);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkAccessorDeclarationTypesIdentical(first, second, getAnnotatedType, message) {
            var firstType = getAnnotatedType(first);
            var secondType = getAnnotatedType(second);
            if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) {
                error(first, message);
            }
        }
        function checkMissingDeclaration(node) {
            checkDecorators(node);
        }
        function checkTypeArgumentConstraints(typeParameters, typeArgumentNodes) {
            var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
            var typeArguments;
            var mapper;
            var result = true;
            for (var i = 0; i < typeParameters.length; i++) {
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    if (!typeArguments) {
                        typeArguments = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, minTypeArgumentCount, ts.isInJavaScriptFile(typeArgumentNodes[i]));
                        mapper = createTypeMapper(typeParameters, typeArguments);
                    }
                    var typeArgument = typeArguments[i];
                    result = result && checkTypeAssignableTo(typeArgument, instantiateType(constraint, mapper), typeArgumentNodes[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                }
            }
            return result;
        }
        function checkTypeReferenceNode(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            if (node.kind === 159 /* TypeReference */ && node.typeName.jsdocDotPos !== undefined && !ts.isInJavaScriptFile(node) && !ts.isInJSDoc(node)) {
                grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
            var type = getTypeFromTypeReference(node);
            if (type !== unknownType) {
                if (node.typeArguments) {
                    // Do type argument local checks only if referenced type is successfully resolved
                    ts.forEach(node.typeArguments, checkSourceElement);
                    if (produceDiagnostics) {
                        var symbol = getNodeLinks(node).resolvedSymbol;
                        if (!symbol) {
                            // There is no resolved symbol cached if the type resolved to a builtin
                            // via JSDoc type reference resolution (eg, Boolean became boolean), none
                            // of which are generic when they have no associated symbol
                            // (additionally, JSDoc's index signature syntax, Object<string, T> actually uses generic syntax without being generic)
                            if (!ts.isJSDocIndexSignature(node)) {
                                error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
                            }
                            return;
                        }
                        var typeParameters = symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters;
                        if (!typeParameters && getObjectFlags(type) & 4 /* Reference */) {
                            typeParameters = type.target.localTypeParameters;
                        }
                        checkTypeArgumentConstraints(typeParameters, node.typeArguments);
                    }
                }
                if (type.flags & 16 /* Enum */ && getNodeLinks(node).resolvedSymbol.flags & 8 /* EnumMember */) {
                    error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
                }
            }
        }
        function checkTypeQuery(node) {
            getTypeFromTypeQueryNode(node);
        }
        function checkTypeLiteral(node) {
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkObjectTypeForDuplicateDeclarations(node);
            }
        }
        function checkArrayType(node) {
            checkSourceElement(node.elementType);
        }
        function checkTupleType(node) {
            // Grammar checking
            var hasErrorFromDisallowedTrailingComma = checkGrammarForDisallowedTrailingComma(node.elementTypes);
            if (!hasErrorFromDisallowedTrailingComma && node.elementTypes.length === 0) {
                grammarErrorOnNode(node, ts.Diagnostics.A_tuple_type_element_list_cannot_be_empty);
            }
            ts.forEach(node.elementTypes, checkSourceElement);
        }
        function checkUnionOrIntersectionType(node) {
            ts.forEach(node.types, checkSourceElement);
        }
        function checkIndexedAccessIndexType(type, accessNode) {
            if (!(type.flags & 524288 /* IndexedAccess */)) {
                return type;
            }
            // Check if the index type is assignable to 'keyof T' for the object type.
            var objectType = type.objectType;
            var indexType = type.indexType;
            if (isTypeAssignableTo(indexType, getIndexType(objectType))) {
                if (accessNode.kind === 180 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) &&
                    getObjectFlags(objectType) & 32 /* Mapped */ && objectType.declaration.readonlyToken) {
                    error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
                return type;
            }
            // Check if we're indexing with a numeric type and if either object or index types
            // is a generic type with a constraint that has a numeric index signature.
            if (getIndexInfoOfType(getApparentType(objectType), 1 /* Number */) && isTypeAssignableToKind(indexType, 84 /* NumberLike */)) {
                return type;
            }
            error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
            return type;
        }
        function checkIndexedAccessType(node) {
            checkSourceElement(node.objectType);
            checkSourceElement(node.indexType);
            checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node);
        }
        function checkMappedType(node) {
            checkSourceElement(node.typeParameter);
            checkSourceElement(node.type);
            var type = getTypeFromMappedTypeNode(node);
            var constraintType = getConstraintTypeFromMappedType(type);
            checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint);
        }
        function isPrivateWithinAmbient(node) {
            return ts.hasModifier(node, 8 /* Private */) && ts.isInAmbientContext(node);
        }
        function getEffectiveDeclarationFlags(n, flagsToCheck) {
            var flags = ts.getCombinedModifierFlags(n);
            // children of classes (even ambient classes) should not be marked as ambient or export
            // because those flags have no useful semantics there.
            if (n.parent.kind !== 230 /* InterfaceDeclaration */ &&
                n.parent.kind !== 229 /* ClassDeclaration */ &&
                n.parent.kind !== 199 /* ClassExpression */ &&
                ts.isInAmbientContext(n)) {
                if (!(flags & 2 /* Ambient */)) {
                    // It is nested in an ambient context, which means it is automatically exported
                    flags |= 1 /* Export */;
                }
                flags |= 2 /* Ambient */;
            }
            return flags & flagsToCheck;
        }
        function checkFunctionOrConstructorSymbol(symbol) {
            if (!produceDiagnostics) {
                return;
            }
            function getCanonicalOverload(overloads, implementation) {
                // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
                // Error on all deviations from this canonical set of flags
                // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
                // report the errors on those. To achieve this, we will say that the implementation is
                // the canonical signature only if it is in the same container as the first overload
                var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
                return implementationSharesContainerWithFirstOverload ? implementation : overloads[0];
            }
            function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) {
                // Error if some overloads have a flag that is not shared by all overloads. To find the
                // deviations, we XOR someOverloadFlags with allOverloadFlags
                var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
                if (someButNotAllOverloadFlags !== 0) {
                    var canonicalFlags_1 = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
                    ts.forEach(overloads, function (o) {
                        var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags_1;
                        if (deviation & 1 /* Export */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
                        }
                        else if (deviation & 2 /* Ambient */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
                        }
                        else if (deviation & (8 /* Private */ | 16 /* Protected */)) {
                            error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
                        }
                        else if (deviation & 128 /* Abstract */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
                        }
                    });
                }
            }
            function checkQuestionTokenAgreementBetweenOverloads(overloads, implementation, someHaveQuestionToken, allHaveQuestionToken) {
                if (someHaveQuestionToken !== allHaveQuestionToken) {
                    var canonicalHasQuestionToken_1 = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation));
                    ts.forEach(overloads, function (o) {
                        var deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken_1;
                        if (deviation) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required);
                        }
                    });
                }
            }
            var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 8 /* Private */ | 16 /* Protected */ | 128 /* Abstract */;
            var someNodeFlags = 0 /* None */;
            var allNodeFlags = flagsToCheck;
            var someHaveQuestionToken = false;
            var allHaveQuestionToken = true;
            var hasOverloads = false;
            var bodyDeclaration;
            var lastSeenNonAmbientDeclaration;
            var previousDeclaration;
            var declarations = symbol.declarations;
            var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0;
            function reportImplementationExpectedError(node) {
                if (node.name && ts.nodeIsMissing(node.name)) {
                    return;
                }
                var seen = false;
                var subsequentNode = ts.forEachChild(node.parent, function (c) {
                    if (seen) {
                        return c;
                    }
                    else {
                        seen = c === node;
                    }
                });
                // We may be here because of some extra nodes between overloads that could not be parsed into a valid node.
                // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
                if (subsequentNode && subsequentNode.pos === node.end) {
                    if (subsequentNode.kind === node.kind) {
                        var errorNode_1 = subsequentNode.name || subsequentNode;
                        // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!)
                        var subsequentName = subsequentNode.name;
                        if (node.name && subsequentName &&
                            (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) ||
                                !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) {
                            var reportError = (node.kind === 151 /* MethodDeclaration */ || node.kind === 150 /* MethodSignature */) &&
                                ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */);
                            // we can get here in two cases
                            // 1. mixed static and instance class members
                            // 2. something with the same name was defined before the set of overloads that prevents them from merging
                            // here we'll report error only for the first case since for second we should already report error in binder
                            if (reportError) {
                                var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static;
                                error(errorNode_1, diagnostic);
                            }
                            return;
                        }
                        else if (ts.nodeIsPresent(subsequentNode.body)) {
                            error(errorNode_1, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name));
                            return;
                        }
                    }
                }
                var errorNode = node.name || node;
                if (isConstructor) {
                    error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing);
                }
                else {
                    // Report different errors regarding non-consecutive blocks of declarations depending on whether
                    // the node in question is abstract.
                    if (ts.hasModifier(node, 128 /* Abstract */)) {
                        error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive);
                    }
                    else {
                        error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration);
                    }
                }
            }
            var duplicateFunctionDeclaration = false;
            var multipleConstructorImplementation = false;
            for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) {
                var current = declarations_4[_i];
                var node = current;
                var inAmbientContext = ts.isInAmbientContext(node);
                var inAmbientContextOrInterface = node.parent.kind === 230 /* InterfaceDeclaration */ || node.parent.kind === 163 /* TypeLiteral */ || inAmbientContext;
                if (inAmbientContextOrInterface) {
                    // check if declarations are consecutive only if they are non-ambient
                    // 1. ambient declarations can be interleaved
                    // i.e. this is legal
                    //     declare function foo();
                    //     declare function bar();
                    //     declare function foo();
                    // 2. mixing ambient and non-ambient declarations is a separate error that will be reported - do not want to report an extra one
                    previousDeclaration = undefined;
                }
                if (node.kind === 228 /* FunctionDeclaration */ || node.kind === 151 /* MethodDeclaration */ || node.kind === 150 /* MethodSignature */ || node.kind === 152 /* Constructor */) {
                    var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
                    someNodeFlags |= currentNodeFlags;
                    allNodeFlags &= currentNodeFlags;
                    someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node);
                    allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node);
                    if (ts.nodeIsPresent(node.body) && bodyDeclaration) {
                        if (isConstructor) {
                            multipleConstructorImplementation = true;
                        }
                        else {
                            duplicateFunctionDeclaration = true;
                        }
                    }
                    else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
                        reportImplementationExpectedError(previousDeclaration);
                    }
                    if (ts.nodeIsPresent(node.body)) {
                        if (!bodyDeclaration) {
                            bodyDeclaration = node;
                        }
                    }
                    else {
                        hasOverloads = true;
                    }
                    previousDeclaration = node;
                    if (!inAmbientContextOrInterface) {
                        lastSeenNonAmbientDeclaration = node;
                    }
                }
            }
            if (multipleConstructorImplementation) {
                ts.forEach(declarations, function (declaration) {
                    error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed);
                });
            }
            if (duplicateFunctionDeclaration) {
                ts.forEach(declarations, function (declaration) {
                    error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Duplicate_function_implementation);
                });
            }
            // Abstract methods can't have an implementation -- in particular, they don't need one.
            if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
                !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) {
                reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
            }
            if (hasOverloads) {
                checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
                checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken);
                if (bodyDeclaration) {
                    var signatures = getSignaturesOfSymbol(symbol);
                    var bodySignature = getSignatureFromDeclaration(bodyDeclaration);
                    for (var _a = 0, signatures_7 = signatures; _a < signatures_7.length; _a++) {
                        var signature = signatures_7[_a];
                        if (!isImplementationCompatibleWithOverload(bodySignature, signature)) {
                            error(signature.declaration, ts.Diagnostics.Overload_signature_is_not_compatible_with_function_implementation);
                            break;
                        }
                    }
                }
            }
        }
        function checkExportsOnMergedDeclarations(node) {
            if (!produceDiagnostics) {
                return;
            }
            // if localSymbol is defined on node then node itself is exported - check is required
            var symbol = node.localSymbol;
            if (!symbol) {
                // local symbol is undefined => this declaration is non-exported.
                // however symbol might contain other declarations that are exported
                symbol = getSymbolOfNode(node);
                if (!symbol.exportSymbol) {
                    // this is a pure local symbol (all declarations are non-exported) - no need to check anything
                    return;
                }
            }
            // run the check only for the first declaration in the list
            if (ts.getDeclarationOfKind(symbol, node.kind) !== node) {
                return;
            }
            var exportedDeclarationSpaces = 0 /* None */;
            var nonExportedDeclarationSpaces = 0 /* None */;
            var defaultExportedDeclarationSpaces = 0 /* None */;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var d = _a[_i];
                var declarationSpaces = getDeclarationSpaces(d);
                var effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, 1 /* Export */ | 512 /* Default */);
                if (effectiveDeclarationFlags & 1 /* Export */) {
                    if (effectiveDeclarationFlags & 512 /* Default */) {
                        defaultExportedDeclarationSpaces |= declarationSpaces;
                    }
                    else {
                        exportedDeclarationSpaces |= declarationSpaces;
                    }
                }
                else {
                    nonExportedDeclarationSpaces |= declarationSpaces;
                }
            }
            // Spaces for anything not declared a 'default export'.
            var nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces;
            if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) {
                // declaration spaces for exported and non-exported declarations intersect
                for (var _b = 0, _c = symbol.declarations; _b < _c.length; _b++) {
                    var d = _c[_b];
                    var declarationSpaces = getDeclarationSpaces(d);
                    var name = ts.getNameOfDeclaration(d);
                    // Only error on the declarations that contributed to the intersecting spaces.
                    if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
                        error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name));
                    }
                    else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
                        error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name));
                    }
                }
            }
            var DeclarationSpaces;
            (function (DeclarationSpaces) {
                DeclarationSpaces[DeclarationSpaces["None"] = 0] = "None";
                DeclarationSpaces[DeclarationSpaces["ExportValue"] = 1] = "ExportValue";
                DeclarationSpaces[DeclarationSpaces["ExportType"] = 2] = "ExportType";
                DeclarationSpaces[DeclarationSpaces["ExportNamespace"] = 4] = "ExportNamespace";
            })(DeclarationSpaces || (DeclarationSpaces = {}));
            function getDeclarationSpaces(d) {
                switch (d.kind) {
                    case 230 /* InterfaceDeclaration */:
                    case 231 /* TypeAliasDeclaration */:
                    // A jsdoc typedef is, by definition, a type alias
                    case 283 /* JSDocTypedefTag */:
                        return 2 /* ExportType */;
                    case 233 /* ModuleDeclaration */:
                        return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */
                            ? 4 /* ExportNamespace */ | 1 /* ExportValue */
                            : 4 /* ExportNamespace */;
                    case 229 /* ClassDeclaration */:
                    case 232 /* EnumDeclaration */:
                        return 2 /* ExportType */ | 1 /* ExportValue */;
                    // The below options all declare an Alias, which is allowed to merge with other values within the importing module
                    case 237 /* ImportEqualsDeclaration */:
                    case 240 /* NamespaceImport */:
                    case 239 /* ImportClause */:
                        var result_3 = 0 /* None */;
                        var target = resolveAlias(getSymbolOfNode(d));
                        ts.forEach(target.declarations, function (d) { result_3 |= getDeclarationSpaces(d); });
                        return result_3;
                    case 226 /* VariableDeclaration */:
                    case 176 /* BindingElement */:
                    case 228 /* FunctionDeclaration */:
                    case 242 /* ImportSpecifier */:// https://github.com/Microsoft/TypeScript/pull/7591
                        return 1 /* ExportValue */;
                    default:
                        ts.Debug.fail(ts.SyntaxKind[d.kind]);
                }
            }
        }
        function getAwaitedTypeOfPromise(type, errorNode, diagnosticMessage) {
            var promisedType = getPromisedTypeOfPromise(type, errorNode);
            return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage);
        }
        /**
         * Gets the "promised type" of a promise.
         * @param type The type of the promise.
         * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.
         */
        function getPromisedTypeOfPromise(promise, errorNode) {
            //
            //  { // promise
            //      then( // thenFunction
            //          onfulfilled: ( // onfulfilledParameterType
            //              value: T // valueParameterType
            //          ) => any
            //      ): any;
            //  }
            //
            if (isTypeAny(promise)) {
                return undefined;
            }
            var typeAsPromise = promise;
            if (typeAsPromise.promisedTypeOfPromise) {
                return typeAsPromise.promisedTypeOfPromise;
            }
            if (isReferenceToType(promise, getGlobalPromiseType(/*reportErrors*/ false))) {
                return typeAsPromise.promisedTypeOfPromise = promise.typeArguments[0];
            }
            var thenFunction = getTypeOfPropertyOfType(promise, "then");
            if (isTypeAny(thenFunction)) {
                return undefined;
            }
            var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : ts.emptyArray;
            if (thenSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method);
                }
                return undefined;
            }
            var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 524288 /* NEUndefinedOrNull */);
            if (isTypeAny(onfulfilledParameterType)) {
                return undefined;
            }
            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
            if (onfulfilledParameterSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback);
                }
                return undefined;
            }
            return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), /*subtypeReduction*/ true);
        }
        /**
         * Gets the "awaited type" of a type.
         * @param type The type to await.
         * @remarks The "awaited type" of an expression is its "promised type" if the expression is a
         * Promise-like type; otherwise, it is the type of the expression. This is used to reflect
         * The runtime behavior of the `await` keyword.
         */
        function checkAwaitedType(type, errorNode, diagnosticMessage) {
            return getAwaitedType(type, errorNode, diagnosticMessage) || unknownType;
        }
        function getAwaitedType(type, errorNode, diagnosticMessage) {
            var typeAsAwaitable = type;
            if (typeAsAwaitable.awaitedTypeOfType) {
                return typeAsAwaitable.awaitedTypeOfType;
            }
            if (isTypeAny(type)) {
                return typeAsAwaitable.awaitedTypeOfType = type;
            }
            if (type.flags & 65536 /* Union */) {
                var types = void 0;
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var constituentType = _a[_i];
                    types = ts.append(types, getAwaitedType(constituentType, errorNode, diagnosticMessage));
                }
                if (!types) {
                    return undefined;
                }
                return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
            }
            var promisedType = getPromisedTypeOfPromise(type);
            if (promisedType) {
                if (type.id === promisedType.id || ts.indexOf(awaitedTypeStack, promisedType.id) >= 0) {
                    // Verify that we don't have a bad actor in the form of a promise whose
                    // promised type is the same as the promise type, or a mutually recursive
                    // promise. If so, we return undefined as we cannot guess the shape. If this
                    // were the actual case in the JavaScript, this Promise would never resolve.
                    //
                    // An example of a bad actor with a singly-recursive promise type might
                    // be:
                    //
                    //  interface BadPromise {
                    //      then(
                    //          onfulfilled: (value: BadPromise) => any,
                    //          onrejected: (error: any) => any): BadPromise;
                    //  }
                    // The above interface will pass the PromiseLike check, and return a
                    // promised type of `BadPromise`. Since this is a self reference, we
                    // don't want to keep recursing ad infinitum.
                    //
                    // An example of a bad actor in the form of a mutually-recursive
                    // promise type might be:
                    //
                    //  interface BadPromiseA {
                    //      then(
                    //          onfulfilled: (value: BadPromiseB) => any,
                    //          onrejected: (error: any) => any): BadPromiseB;
                    //  }
                    //
                    //  interface BadPromiseB {
                    //      then(
                    //          onfulfilled: (value: BadPromiseA) => any,
                    //          onrejected: (error: any) => any): BadPromiseA;
                    //  }
                    //
                    if (errorNode) {
                        error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
                    }
                    return undefined;
                }
                // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
                // See the comments above for more information.
                awaitedTypeStack.push(type.id);
                var awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage);
                awaitedTypeStack.pop();
                if (!awaitedType) {
                    return undefined;
                }
                return typeAsAwaitable.awaitedTypeOfType = awaitedType;
            }
            // The type was not a promise, so it could not be unwrapped any further.
            // As long as the type does not have a callable "then" property, it is
            // safe to return the type; otherwise, an error will be reported in
            // the call to getNonThenableType and we will return undefined.
            //
            // An example of a non-promise "thenable" might be:
            //
            //  await { then(): void {} }
            //
            // The "thenable" does not match the minimal definition for a promise. When
            // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
            // will never settle. We treat this as an error to help flag an early indicator
            // of a runtime problem. If the user wants to return this value from an async
            // function, they would need to wrap it in some other value. If they want it to
            // be treated as a promise, they can cast to <any>.
            var thenFunction = getTypeOfPropertyOfType(type, "then");
            if (thenFunction && getSignaturesOfType(thenFunction, 0 /* Call */).length > 0) {
                if (errorNode) {
                    ts.Debug.assert(!!diagnosticMessage);
                    error(errorNode, diagnosticMessage);
                }
                return undefined;
            }
            return typeAsAwaitable.awaitedTypeOfType = type;
        }
        /**
         * Checks the return type of an async function to ensure it is a compatible
         * Promise implementation.
         *
         * This checks that an async function has a valid Promise-compatible return type,
         * and returns the *awaited type* of the promise. An async function has a valid
         * Promise-compatible return type if the resolved value of the return type has a
         * construct signature that takes in an `initializer` function that in turn supplies
         * a `resolve` function as one of its arguments and results in an object with a
         * callable `then` signature.
         *
         * @param node The signature to check
         */
        function checkAsyncFunctionReturnType(node) {
            // As part of our emit for an async function, we will need to emit the entity name of
            // the return type annotation as an expression. To meet the necessary runtime semantics
            // for __awaiter, we must also check that the type of the declaration (e.g. the static
            // side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
            //
            // An example might be (from lib.es6.d.ts):
            //
            //  interface Promise<T> { ... }
            //  interface PromiseConstructor {
            //      new <T>(...): Promise<T>;
            //  }
            //  declare var Promise: PromiseConstructor;
            //
            // When an async function declares a return type annotation of `Promise<T>`, we
            // need to get the type of the `Promise` variable declaration above, which would
            // be `PromiseConstructor`.
            //
            // The same case applies to a class:
            //
            //  declare class Promise<T> {
            //      constructor(...);
            //      then<U>(...): Promise<U>;
            //  }
            //
            var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
            var returnType = getTypeFromTypeNode(returnTypeNode);
            if (languageVersion >= 2 /* ES2015 */) {
                if (returnType === unknownType) {
                    return unknownType;
                }
                var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
                if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
                    // The promise type was not a valid type reference to the global promise type, so we
                    // report an error and return the unknown type.
                    error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
                    return unknownType;
                }
            }
            else {
                // Always mark the type node as referenced if it points to a value
                markTypeNodeAsReferenced(returnTypeNode);
                if (returnType === unknownType) {
                    return unknownType;
                }
                var promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode);
                if (promiseConstructorName === undefined) {
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
                    return unknownType;
                }
                var promiseConstructorSymbol = resolveEntityName(promiseConstructorName, 107455 /* Value */, /*ignoreErrors*/ true);
                var promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType;
                if (promiseConstructorType === unknownType) {
                    if (promiseConstructorName.kind === 71 /* Identifier */ && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
                        error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
                    }
                    else {
                        error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    }
                    return unknownType;
                }
                var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true);
                if (globalPromiseConstructorLikeType === emptyObjectType) {
                    // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
                    // compatibility with __awaiter.
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    return unknownType;
                }
                if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
                    return unknownType;
                }
                // Verify there is no local declaration that could collide with the promise constructor.
                var rootName = promiseConstructorName && getFirstIdentifier(promiseConstructorName);
                var collidingSymbol = getSymbol(node.locals, rootName.escapedText, 107455 /* Value */);
                if (collidingSymbol) {
                    error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName));
                    return unknownType;
                }
            }
            // Get and return the awaited type of the return type.
            return checkAwaitedType(returnType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /** Check a decorator */
        function checkDecorator(node) {
            var signature = getResolvedSignature(node);
            var returnType = getReturnTypeOfSignature(signature);
            if (returnType.flags & 1 /* Any */) {
                return;
            }
            var expectedReturnType;
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            var errorInfo;
            switch (node.parent.kind) {
                case 229 /* ClassDeclaration */:
                    var classSymbol = getSymbolOfNode(node.parent);
                    var classConstructorType = getTypeOfSymbol(classSymbol);
                    expectedReturnType = getUnionType([classConstructorType, voidType]);
                    break;
                case 146 /* Parameter */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any);
                    break;
                case 149 /* PropertyDeclaration */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any);
                    break;
                case 151 /* MethodDeclaration */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    var methodType = getTypeOfNode(node.parent);
                    var descriptorType = createTypedPropertyDescriptorType(methodType);
                    expectedReturnType = getUnionType([descriptorType, voidType]);
                    break;
            }
            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, errorInfo);
        }
        /**
         * If a TypeNode can be resolved to a value symbol imported from an external module, it is
         * marked as referenced to prevent import elision.
         */
        function markTypeNodeAsReferenced(node) {
            markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node));
        }
        function markEntityNameOrEntityExpressionAsReference(typeName) {
            if (!typeName)
                return;
            var rootName = getFirstIdentifier(typeName);
            var meaning = (typeName.kind === 71 /* Identifier */ ? 793064 /* Type */ : 1920 /* Namespace */) | 2097152 /* Alias */;
            var rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isRefernce*/ true);
            if (rootSymbol
                && rootSymbol.flags & 2097152 /* Alias */
                && symbolIsValue(rootSymbol)
                && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
                markAliasSymbolAsReferenced(rootSymbol);
            }
        }
        /**
         * This function marks the type used for metadata decorator as referenced if it is import
         * from external module.
         * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
         * union and intersection type
         * @param node
         */
        function markDecoratorMedataDataTypeNodeAsReferenced(node) {
            var entityName = getEntityNameForDecoratorMetadata(node);
            if (entityName && ts.isEntityName(entityName)) {
                markEntityNameOrEntityExpressionAsReference(entityName);
            }
        }
        function getEntityNameForDecoratorMetadata(node) {
            if (node) {
                switch (node.kind) {
                    case 167 /* IntersectionType */:
                    case 166 /* UnionType */:
                        var commonEntityName = void 0;
                        for (var _i = 0, _a = node.types; _i < _a.length; _i++) {
                            var typeNode = _a[_i];
                            var individualEntityName = getEntityNameForDecoratorMetadata(typeNode);
                            if (!individualEntityName) {
                                // Individual is something like string number
                                // So it would be serialized to either that type or object
                                // Safe to return here
                                return undefined;
                            }
                            if (commonEntityName) {
                                // Note this is in sync with the transformation that happens for type node.
                                // Keep this in sync with serializeUnionOrIntersectionType
                                // Verify if they refer to same entity and is identifier
                                // return undefined if they dont match because we would emit object
                                if (!ts.isIdentifier(commonEntityName) ||
                                    !ts.isIdentifier(individualEntityName) ||
                                    commonEntityName.escapedText !== individualEntityName.escapedText) {
                                    return undefined;
                                }
                            }
                            else {
                                commonEntityName = individualEntityName;
                            }
                        }
                        return commonEntityName;
                    case 168 /* ParenthesizedType */:
                        return getEntityNameForDecoratorMetadata(node.type);
                    case 159 /* TypeReference */:
                        return node.typeName;
                }
            }
        }
        function getParameterTypeNodeForDecoratorCheck(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode;
        }
        /** Check the decorators of a node */
        function checkDecorators(node) {
            if (!node.decorators) {
                return;
            }
            // skip this check for nodes that cannot have decorators. These should have already had an error reported by
            // checkGrammarDecorators.
            if (!ts.nodeCanBeDecorated(node)) {
                return;
            }
            if (!compilerOptions.experimentalDecorators) {
                error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
            }
            var firstDecorator = node.decorators[0];
            checkExternalEmitHelpers(firstDecorator, 8 /* Decorate */);
            if (node.kind === 146 /* Parameter */) {
                checkExternalEmitHelpers(firstDecorator, 32 /* Param */);
            }
            if (compilerOptions.emitDecoratorMetadata) {
                checkExternalEmitHelpers(firstDecorator, 16 /* Metadata */);
                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
                switch (node.kind) {
                    case 229 /* ClassDeclaration */:
                        var constructor = ts.getFirstConstructorWithBody(node);
                        if (constructor) {
                            for (var _i = 0, _a = constructor.parameters; _i < _a.length; _i++) {
                                var parameter = _a[_i];
                                markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                            }
                        }
                        break;
                    case 151 /* MethodDeclaration */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        for (var _b = 0, _c = node.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node));
                        break;
                    case 149 /* PropertyDeclaration */:
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node));
                        break;
                    case 146 /* Parameter */:
                        markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
                        break;
                }
            }
            ts.forEach(node.decorators, checkDecorator);
        }
        function checkFunctionDeclaration(node) {
            if (produceDiagnostics) {
                checkFunctionOrMethodDeclaration(node);
                checkGrammarForGenerator(node);
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithCapturedNewTargetVariable(node, node.name);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function checkJSDocTypedefTag(node) {
            if (!node.typeExpression) {
                // If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
                error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
            }
        }
        function checkJSDocParameterTag(node) {
            checkSourceElement(node.typeExpression);
            if (!ts.getParameterSymbolFromJSDoc(node)) {
                error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 143 /* QualifiedName */ ? node.name.right : node.name));
            }
        }
        function checkJSDocAugmentsTag(node) {
            var classLike = ts.getJSDocHost(node);
            if (!ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
                return;
            }
            var augmentsTags = ts.getAllJSDocTagsOfKind(classLike, 277 /* JSDocAugmentsTag */);
            ts.Debug.assert(augmentsTags.length > 0);
            if (augmentsTags.length > 1) {
                error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag);
            }
            var name = getIdentifierFromEntityNameExpression(node.class.expression);
            var extend = ts.getClassExtendsHeritageClauseElement(classLike);
            if (extend) {
                var className = getIdentifierFromEntityNameExpression(extend.expression);
                if (className && name.escapedText !== className.escapedText) {
                    error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className));
                }
            }
        }
        function getIdentifierFromEntityNameExpression(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return node;
                case 179 /* PropertyAccessExpression */:
                    return node.name;
                default:
                    return undefined;
            }
        }
        function checkFunctionOrMethodDeclaration(node) {
            checkDecorators(node);
            checkSignatureDeclaration(node);
            var functionFlags = ts.getFunctionFlags(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name && node.name.kind === 144 /* ComputedPropertyName */) {
                // This check will account for methods in class/interface declarations,
                // as well as accessors in classes/object literals
                checkComputedPropertyName(node.name);
            }
            if (!ts.hasDynamicName(node)) {
                // first we want to check the local symbol that contain this declaration
                // - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol
                // - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode
                var symbol = getSymbolOfNode(node);
                var localSymbol = node.localSymbol || symbol;
                // Since the javascript won't do semantic analysis like typescript,
                // if the javascript file comes before the typescript file and both contain same name functions,
                // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
                var firstDeclaration = ts.find(localSymbol.declarations, 
                // Get first non javascript function declaration
                function (declaration) { return declaration.kind === node.kind && !(declaration.flags & 65536 /* JavaScriptFile */); });
                // Only type check the symbol once
                if (node === firstDeclaration) {
                    checkFunctionOrConstructorSymbol(localSymbol);
                }
                if (symbol.parent) {
                    // run check once for the first declaration
                    if (ts.getDeclarationOfKind(symbol, node.kind) === node) {
                        // run check on export symbol to check that modifiers agree across all exported declarations
                        checkFunctionOrConstructorSymbol(symbol);
                    }
                }
            }
            checkSourceElement(node.body);
            var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
            if ((functionFlags & 1 /* Generator */) === 0) {
                var returnOrPromisedType = returnTypeNode && (functionFlags & 2 /* Async */
                    ? checkAsyncFunctionReturnType(node) // Async function
                    : getTypeFromTypeNode(returnTypeNode)); // normal function
                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
            }
            if (produceDiagnostics && !returnTypeNode) {
                // Report an implicit any error if there is no body, no explicit return type, and node is not a private method
                // in an ambient context
                if (noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
                    reportImplicitAnyError(node, anyType);
                }
                if (functionFlags & 1 /* Generator */ && ts.nodeIsPresent(node.body)) {
                    // A generator with a body and no type annotation can still cause errors. It can error if the
                    // yielded values have no common supertype, or it can give an implicit any error if it has no
                    // yielded values. The only way to trigger these errors is to try checking its return type.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
            }
            registerForUnusedIdentifiersCheck(node);
        }
        function registerForUnusedIdentifiersCheck(node) {
            if (deferredUnusedIdentifierNodes) {
                deferredUnusedIdentifierNodes.push(node);
            }
        }
        function checkUnusedIdentifiers() {
            if (deferredUnusedIdentifierNodes) {
                for (var _i = 0, deferredUnusedIdentifierNodes_1 = deferredUnusedIdentifierNodes; _i < deferredUnusedIdentifierNodes_1.length; _i++) {
                    var node = deferredUnusedIdentifierNodes_1[_i];
                    switch (node.kind) {
                        case 265 /* SourceFile */:
                        case 233 /* ModuleDeclaration */:
                            checkUnusedModuleMembers(node);
                            break;
                        case 229 /* ClassDeclaration */:
                        case 199 /* ClassExpression */:
                            checkUnusedClassMembers(node);
                            checkUnusedTypeParameters(node);
                            break;
                        case 230 /* InterfaceDeclaration */:
                            checkUnusedTypeParameters(node);
                            break;
                        case 207 /* Block */:
                        case 235 /* CaseBlock */:
                        case 214 /* ForStatement */:
                        case 215 /* ForInStatement */:
                        case 216 /* ForOfStatement */:
                            checkUnusedLocalsAndParameters(node);
                            break;
                        case 152 /* Constructor */:
                        case 186 /* FunctionExpression */:
                        case 228 /* FunctionDeclaration */:
                        case 187 /* ArrowFunction */:
                        case 151 /* MethodDeclaration */:
                        case 153 /* GetAccessor */:
                        case 154 /* SetAccessor */:
                            if (node.body) {
                                checkUnusedLocalsAndParameters(node);
                            }
                            checkUnusedTypeParameters(node);
                            break;
                        case 150 /* MethodSignature */:
                        case 155 /* CallSignature */:
                        case 156 /* ConstructSignature */:
                        case 157 /* IndexSignature */:
                        case 160 /* FunctionType */:
                        case 161 /* ConstructorType */:
                            checkUnusedTypeParameters(node);
                            break;
                        case 231 /* TypeAliasDeclaration */:
                            checkUnusedTypeParameters(node);
                            break;
                    }
                }
            }
        }
        function checkUnusedLocalsAndParameters(node) {
            if (node.parent.kind !== 230 /* InterfaceDeclaration */ && noUnusedIdentifiers && !ts.isInAmbientContext(node)) {
                node.locals.forEach(function (local) {
                    if (!local.isReferenced) {
                        if (local.valueDeclaration && ts.getRootDeclaration(local.valueDeclaration).kind === 146 /* Parameter */) {
                            var parameter = ts.getRootDeclaration(local.valueDeclaration);
                            var name = ts.getNameOfDeclaration(local.valueDeclaration);
                            if (compilerOptions.noUnusedParameters &&
                                !ts.isParameterPropertyDeclaration(parameter) &&
                                !ts.parameterIsThisKeyword(parameter) &&
                                !parameterNameStartsWithUnderscore(name)) {
                                error(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local));
                            }
                        }
                        else if (compilerOptions.noUnusedLocals) {
                            ts.forEach(local.declarations, function (d) { return errorUnusedLocal(d, ts.symbolName(local)); });
                        }
                    }
                });
            }
        }
        function isRemovedPropertyFromObjectSpread(node) {
            if (ts.isBindingElement(node) && ts.isObjectBindingPattern(node.parent)) {
                var lastElement = ts.lastOrUndefined(node.parent.elements);
                return lastElement !== node && !!lastElement.dotDotDotToken;
            }
            return false;
        }
        function errorUnusedLocal(declaration, name) {
            var node = ts.getNameOfDeclaration(declaration) || declaration;
            if (isIdentifierThatStartsWithUnderScore(node)) {
                var declaration_2 = ts.getRootDeclaration(node.parent);
                if ((declaration_2.kind === 226 /* VariableDeclaration */ && ts.isForInOrOfStatement(declaration_2.parent.parent)) ||
                    declaration_2.kind === 145 /* TypeParameter */) {
                    return;
                }
            }
            if (!isRemovedPropertyFromObjectSpread(node.kind === 71 /* Identifier */ ? node.parent : node)) {
                error(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name);
            }
        }
        function parameterNameStartsWithUnderscore(parameterName) {
            return parameterName && isIdentifierThatStartsWithUnderScore(parameterName);
        }
        function isIdentifierThatStartsWithUnderScore(node) {
            return node.kind === 71 /* Identifier */ && ts.idText(node).charCodeAt(0) === 95 /* _ */;
        }
        function checkUnusedClassMembers(node) {
            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
                if (node.members) {
                    for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        if (member.kind === 151 /* MethodDeclaration */ || member.kind === 149 /* PropertyDeclaration */) {
                            if (!member.symbol.isReferenced && ts.hasModifier(member, 8 /* Private */)) {
                                error(member.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(member.symbol));
                            }
                        }
                        else if (member.kind === 152 /* Constructor */) {
                            for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                                var parameter = _c[_b];
                                if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) {
                                    error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol));
                                }
                            }
                        }
                    }
                }
            }
        }
        function checkUnusedTypeParameters(node) {
            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
                if (node.typeParameters) {
                    // Only report errors on the last declaration for the type parameter container;
                    // this ensures that all uses have been accounted for.
                    var symbol = getSymbolOfNode(node);
                    var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations);
                    if (lastDeclaration !== node) {
                        return;
                    }
                    for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) {
                        var typeParameter = _a[_i];
                        if (!getMergedSymbol(typeParameter.symbol).isReferenced && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) {
                            error(typeParameter.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(typeParameter.symbol));
                        }
                    }
                }
            }
        }
        function checkUnusedModuleMembers(node) {
            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
                node.locals.forEach(function (local) {
                    if (!local.isReferenced && !local.exportSymbol) {
                        for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) {
                            var declaration = _a[_i];
                            if (!ts.isAmbientModule(declaration)) {
                                errorUnusedLocal(declaration, ts.symbolName(local));
                            }
                        }
                    }
                });
            }
        }
        function checkBlock(node) {
            // Grammar checking for SyntaxKind.Block
            if (node.kind === 207 /* Block */) {
                checkGrammarStatementInAmbientContext(node);
            }
            if (ts.isFunctionOrModuleBlock(node)) {
                var saveFlowAnalysisDisabled = flowAnalysisDisabled;
                ts.forEach(node.statements, checkSourceElement);
                flowAnalysisDisabled = saveFlowAnalysisDisabled;
            }
            else {
                ts.forEach(node.statements, checkSourceElement);
            }
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkCollisionWithArgumentsInGeneratedCode(node) {
            // no rest parameters \ declaration context \ overload - no codegen impact
            if (!ts.hasRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) {
                return;
            }
            ts.forEach(node.parameters, function (p) {
                if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) {
                    error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
                }
            });
        }
        function needCollisionCheckForIdentifier(node, identifier, name) {
            if (!(identifier && identifier.escapedText === name)) {
                return false;
            }
            if (node.kind === 149 /* PropertyDeclaration */ ||
                node.kind === 148 /* PropertySignature */ ||
                node.kind === 151 /* MethodDeclaration */ ||
                node.kind === 150 /* MethodSignature */ ||
                node.kind === 153 /* GetAccessor */ ||
                node.kind === 154 /* SetAccessor */) {
                // it is ok to have member named '_super' or '_this' - member access is always qualified
                return false;
            }
            if (ts.isInAmbientContext(node)) {
                // ambient context - no codegen impact
                return false;
            }
            var root = ts.getRootDeclaration(node);
            if (root.kind === 146 /* Parameter */ && ts.nodeIsMissing(root.parent.body)) {
                // just an overload - no codegen impact
                return false;
            }
            return true;
        }
        function checkCollisionWithCapturedThisVariable(node, name) {
            if (needCollisionCheckForIdentifier(node, name, "_this")) {
                potentialThisCollisions.push(node);
            }
        }
        function checkCollisionWithCapturedNewTargetVariable(node, name) {
            if (needCollisionCheckForIdentifier(node, name, "_newTarget")) {
                potentialNewTargetCollisions.push(node);
            }
        }
        // this function will run after checking the source file so 'CaptureThis' is correct for all nodes
        function checkIfThisIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                    var isDeclaration_1 = node.kind !== 71 /* Identifier */;
                    if (isDeclaration_1) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
                    }
                    return true;
                }
            });
        }
        function checkIfNewTargetIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 8 /* CaptureNewTarget */) {
                    var isDeclaration_2 = node.kind !== 71 /* Identifier */;
                    if (isDeclaration_2) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference);
                    }
                    return true;
                }
            });
        }
        function checkCollisionWithCapturedSuperVariable(node, name) {
            if (!needCollisionCheckForIdentifier(node, name, "_super")) {
                return;
            }
            // bubble up and find containing type
            var enclosingClass = ts.getContainingClass(node);
            // if containing type was not found or it is ambient - exit (no codegen)
            if (!enclosingClass || ts.isInAmbientContext(enclosingClass)) {
                return;
            }
            if (ts.getClassExtendsHeritageClauseElement(enclosingClass)) {
                var isDeclaration_3 = node.kind !== 71 /* Identifier */;
                if (isDeclaration_3) {
                    error(node, ts.Diagnostics.Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference);
                }
                else {
                    error(node, ts.Diagnostics.Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference);
                }
            }
        }
        function checkCollisionWithRequireExportsInGeneratedCode(node, name) {
            // No need to check for require or exports for ES6 modules and later
            if (modulekind >= ts.ModuleKind.ES2015) {
                return;
            }
            if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (node.kind === 233 /* ModuleDeclaration */ && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 265 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
                // If the declaration happens to be in external module, report error that require and exports are reserved keywords
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkCollisionWithGlobalPromiseInGeneratedCode(node, name) {
            if (languageVersion >= 4 /* ES2017 */ || !needCollisionCheckForIdentifier(node, name, "Promise")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (node.kind === 233 /* ModuleDeclaration */ && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 265 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 1024 /* HasAsyncFunctions */) {
                // If the declaration happens to be in external module, report error that Promise is a reserved identifier.
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkVarDeclaredNamesNotShadowed(node) {
            // - ScriptBody : StatementList
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // - Block : { StatementList }
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // Variable declarations are hoisted to the top of their function scope. They can shadow
            // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition
            // by the binder as the declaration scope is different.
            // A non-initialized declaration is a no-op as the block declaration will resolve before the var
            // declaration. the problem is if the declaration has an initializer. this will act as a write to the
            // block declared value. this is fine for let, but not const.
            // Only consider declarations with initializers, uninitialized const declarations will not
            // step on a let/const variable.
            // Do not consider const and const declarations, as duplicate block-scoped declarations
            // are handled by the binder.
            // We are only looking for const declarations that step on let\const declarations from a
            // different scope. e.g.:
            //      {
            //          const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
            //          const x = 0; // symbol for this declaration will be 'symbol'
            //      }
            // skip block-scoped variables and parameters
            if ((ts.getCombinedNodeFlags(node) & 3 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
                return;
            }
            // skip variable declarations that don't have initializers
            // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
            // so we'll always treat binding elements as initialized
            if (node.kind === 226 /* VariableDeclaration */ && !node.initializer) {
                return;
            }
            var symbol = getSymbolOfNode(node);
            if (symbol.flags & 1 /* FunctionScopedVariable */) {
                if (!ts.isIdentifier(node.name))
                    throw ts.Debug.fail();
                var localDeclarationSymbol = resolveName(node, node.name.escapedText, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
                if (localDeclarationSymbol &&
                    localDeclarationSymbol !== symbol &&
                    localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
                    if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & 3 /* BlockScoped */) {
                        var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 227 /* VariableDeclarationList */);
                        var container = varDeclList.parent.kind === 208 /* VariableStatement */ && varDeclList.parent.parent
                            ? varDeclList.parent.parent
                            : undefined;
                        // names of block-scoped and function scoped variables can collide only
                        // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
                        var namesShareScope = container &&
                            (container.kind === 207 /* Block */ && ts.isFunctionLike(container.parent) ||
                                container.kind === 234 /* ModuleBlock */ ||
                                container.kind === 233 /* ModuleDeclaration */ ||
                                container.kind === 265 /* SourceFile */);
                        // here we know that function scoped variable is shadowed by block scoped one
                        // if they are defined in the same scope - binder has already reported redeclaration error
                        // otherwise if variable has an initializer - show error that initialization will fail
                        // since LHS will be block scoped name instead of function scoped
                        if (!namesShareScope) {
                            var name = symbolToString(localDeclarationSymbol);
                            error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
                        }
                    }
                }
            }
        }
        // Check that a parameter initializer contains no references to parameters declared to the right of itself
        function checkParameterInitializer(node) {
            if (ts.getRootDeclaration(node).kind !== 146 /* Parameter */) {
                return;
            }
            var func = ts.getContainingFunction(node);
            visit(node.initializer);
            function visit(n) {
                if (ts.isTypeNode(n) || ts.isDeclarationName(n)) {
                    // do not dive in types
                    // skip declaration names (i.e. in object literal expressions)
                    return;
                }
                if (n.kind === 179 /* PropertyAccessExpression */) {
                    // skip property names in property access expression
                    return visit(n.expression);
                }
                else if (n.kind === 71 /* Identifier */) {
                    // check FunctionLikeDeclaration.locals (stores parameters\function local variable)
                    // if it contains entry with a specified name
                    var symbol = resolveName(n, n.escapedText, 107455 /* Value */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
                    if (!symbol || symbol === unknownSymbol || !symbol.valueDeclaration) {
                        return;
                    }
                    if (symbol.valueDeclaration === node) {
                        error(n, ts.Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, ts.declarationNameToString(node.name));
                        return;
                    }
                    // locals map for function contain both parameters and function locals
                    // so we need to do a bit of extra work to check if reference is legal
                    var enclosingContainer = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
                    if (enclosingContainer === func) {
                        if (symbol.valueDeclaration.kind === 146 /* Parameter */ ||
                            symbol.valueDeclaration.kind === 176 /* BindingElement */) {
                            // it is ok to reference parameter in initializer if either
                            // - parameter is located strictly on the left of current parameter declaration
                            if (symbol.valueDeclaration.pos < node.pos) {
                                return;
                            }
                            // - parameter is wrapped in function-like entity
                            if (ts.findAncestor(n, function (current) {
                                if (current === node.initializer) {
                                    return "quit";
                                }
                                return ts.isFunctionLike(current.parent) ||
                                    // computed property names/initializers in instance property declaration of class like entities
                                    // are executed in constructor and thus deferred
                                    (current.parent.kind === 149 /* PropertyDeclaration */ &&
                                        !(ts.hasModifier(current.parent, 32 /* Static */)) &&
                                        ts.isClassLike(current.parent.parent));
                            })) {
                                return;
                            }
                            // fall through to report error
                        }
                        error(n, ts.Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(node.name), ts.declarationNameToString(n));
                    }
                }
                else {
                    return ts.forEachChild(n, visit);
                }
            }
        }
        function convertAutoToAny(type) {
            return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type;
        }
        // Check variable, parameter, or property declaration
        function checkVariableLikeDeclaration(node) {
            checkDecorators(node);
            checkSourceElement(node.type);
            // JSDoc `function(string, string): string` syntax results in parameters with no name
            if (!node.name) {
                return;
            }
            // For a computed property, just check the initializer and exit
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 144 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
                if (node.initializer) {
                    checkExpressionCached(node.initializer);
                }
            }
            if (node.kind === 176 /* BindingElement */) {
                if (node.parent.kind === 174 /* ObjectBindingPattern */ && languageVersion < 5 /* ESNext */) {
                    checkExternalEmitHelpers(node, 4 /* Rest */);
                }
                // check computed properties inside property names of binding elements
                if (node.propertyName && node.propertyName.kind === 144 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.propertyName);
                }
                // check private/protected variable access
                var parent = node.parent.parent;
                var parentType = getTypeForBindingElementParent(parent);
                var name = node.propertyName || node.name;
                var property = getPropertyOfType(parentType, ts.getTextOfPropertyName(name));
                markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
                if (parent.initializer && property) {
                    checkPropertyAccessibility(parent, parent.initializer, parentType, property);
                }
            }
            // For a binding pattern, check contained binding elements
            if (ts.isBindingPattern(node.name)) {
                if (node.name.kind === 175 /* ArrayBindingPattern */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 512 /* Read */);
                }
                ts.forEach(node.name.elements, checkSourceElement);
            }
            // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
            if (node.initializer && ts.getRootDeclaration(node).kind === 146 /* Parameter */ && ts.nodeIsMissing(ts.getContainingFunction(node).body)) {
                error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
                return;
            }
            // For a binding pattern, validate the initializer and exit
            if (ts.isBindingPattern(node.name)) {
                // Don't validate for-in initializer as it is already an error
                if (node.initializer && node.parent.parent.kind !== 215 /* ForInStatement */) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
                    checkParameterInitializer(node);
                }
                return;
            }
            var symbol = getSymbolOfNode(node);
            var type = convertAutoToAny(getTypeOfVariableOrParameterOrProperty(symbol));
            if (node === symbol.valueDeclaration) {
                // Node is the primary declaration of the symbol, just validate the initializer
                // Don't validate for-in initializer as it is already an error
                if (node.initializer && node.parent.parent.kind !== 215 /* ForInStatement */) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined);
                    checkParameterInitializer(node);
                }
            }
            else {
                // Node is a secondary declaration, check that type is identical to primary declaration and check that
                // initializer is consistent with type associated with the node
                var declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
                if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
                    error(node.name, ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, ts.declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
                }
                if (node.initializer) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined);
                }
                if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
                    error(ts.getNameOfDeclaration(symbol.valueDeclaration), ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                    error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                }
            }
            if (node.kind !== 149 /* PropertyDeclaration */ && node.kind !== 148 /* PropertySignature */) {
                // We know we don't have a binding pattern or computed name here
                checkExportsOnMergedDeclarations(node);
                if (node.kind === 226 /* VariableDeclaration */ || node.kind === 176 /* BindingElement */) {
                    checkVarDeclaredNamesNotShadowed(node);
                }
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithCapturedNewTargetVariable(node, node.name);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function areDeclarationFlagsIdentical(left, right) {
            if ((left.kind === 146 /* Parameter */ && right.kind === 226 /* VariableDeclaration */) ||
                (left.kind === 226 /* VariableDeclaration */ && right.kind === 146 /* Parameter */)) {
                // Differences in optionality between parameters and variables are allowed.
                return true;
            }
            if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) {
                return false;
            }
            var interestingFlags = 8 /* Private */ |
                16 /* Protected */ |
                256 /* Async */ |
                128 /* Abstract */ |
                64 /* Readonly */ |
                32 /* Static */;
            return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags);
        }
        function checkVariableDeclaration(node) {
            checkGrammarVariableDeclaration(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkBindingElement(node) {
            checkGrammarBindingElement(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkVariableStatement(node) {
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
            ts.forEach(node.declarationList.declarations, checkSourceElement);
        }
        function checkGrammarDisallowedModifiersOnObjectLiteralExpressionMethod(node) {
            // We only disallow modifier on a method declaration if it is a property of object-literal-expression
            if (node.modifiers && node.parent.kind === 178 /* ObjectLiteralExpression */) {
                if (ts.getFunctionFlags(node) & 2 /* Async */) {
                    if (node.modifiers.length > 1) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                }
                else {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                }
            }
        }
        function checkExpressionStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkExpression(node.expression);
        }
        function checkIfStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkExpression(node.expression);
            checkSourceElement(node.thenStatement);
            if (node.thenStatement.kind === 209 /* EmptyStatement */) {
                error(node.thenStatement, ts.Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement);
            }
            checkSourceElement(node.elseStatement);
        }
        function checkDoStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkSourceElement(node.statement);
            checkExpression(node.expression);
        }
        function checkWhileStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkExpression(node.expression);
            checkSourceElement(node.statement);
        }
        function checkForStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.initializer && node.initializer.kind === 227 /* VariableDeclarationList */) {
                    checkGrammarVariableDeclarationList(node.initializer);
                }
            }
            if (node.initializer) {
                if (node.initializer.kind === 227 /* VariableDeclarationList */) {
                    ts.forEach(node.initializer.declarations, checkVariableDeclaration);
                }
                else {
                    checkExpression(node.initializer);
                }
            }
            if (node.condition)
                checkExpression(node.condition);
            if (node.incrementor)
                checkExpression(node.incrementor);
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForOfStatement(node) {
            checkGrammarForInOrForOfStatement(node);
            if (node.kind === 216 /* ForOfStatement */) {
                if (node.awaitModifier) {
                    var functionFlags = ts.getFunctionFlags(ts.getContainingFunction(node));
                    if ((functionFlags & (4 /* Invalid */ | 2 /* Async */)) === 2 /* Async */ && languageVersion < 5 /* ESNext */) {
                        // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper
                        checkExternalEmitHelpers(node, 16384 /* ForAwaitOfIncludes */);
                    }
                }
                else if (compilerOptions.downlevelIteration && languageVersion < 2 /* ES2015 */) {
                    // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled
                    checkExternalEmitHelpers(node, 256 /* ForOfIncludes */);
                }
            }
            // Check the LHS and RHS
            // If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS
            // via checkRightHandSideOfForOf.
            // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference.
            // Then check that the RHS is assignable to it.
            if (node.initializer.kind === 227 /* VariableDeclarationList */) {
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                var varExpr = node.initializer;
                var iteratedType = checkRightHandSideOfForOf(node.expression, node.awaitModifier);
                // There may be a destructuring assignment on the left side
                if (varExpr.kind === 177 /* ArrayLiteralExpression */ || varExpr.kind === 178 /* ObjectLiteralExpression */) {
                    // iteratedType may be undefined. In this case, we still want to check the structure of
                    // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like
                    // to short circuit the type relation checking as much as possible, so we pass the unknownType.
                    checkDestructuringAssignment(varExpr, iteratedType || unknownType);
                }
                else {
                    var leftType = checkExpression(varExpr);
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access);
                    // iteratedType will be undefined if the rightType was missing properties/signatures
                    // required to get its iteratedType (like [Symbol.iterator] or next). This may be
                    // because we accessed properties from anyType, or it may have led to an error inside
                    // getElementTypeOfIterable.
                    if (iteratedType) {
                        checkTypeAssignableTo(iteratedType, leftType, varExpr, /*headMessage*/ undefined);
                    }
                }
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInStatement(node) {
            // Grammar checking
            checkGrammarForInOrForOfStatement(node);
            var rightType = checkNonNullExpression(node.expression);
            // TypeScript 1.0 spec  (April 2014): 5.4
            // In a 'for-in' statement of the form
            // for (let VarDecl in Expr) Statement
            //   VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
            //   and Expr must be an expression of type Any, an object type, or a type parameter type.
            if (node.initializer.kind === 227 /* VariableDeclarationList */) {
                var variable = node.initializer.declarations[0];
                if (variable && ts.isBindingPattern(variable.name)) {
                    error(variable.name, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                // In a 'for-in' statement of the form
                // for (Var in Expr) Statement
                //   Var must be an expression classified as a reference of type Any or the String primitive type,
                //   and Expr must be an expression of type Any, an object type, or a type parameter type.
                var varExpr = node.initializer;
                var leftType = checkExpression(varExpr);
                if (varExpr.kind === 177 /* ArrayLiteralExpression */ || varExpr.kind === 178 /* ObjectLiteralExpression */) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
                }
                else {
                    // run check only former check succeeded to avoid cascading errors
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access);
                }
            }
            // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
            // in this case error about missing name is already reported - do not report extra one
            if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) {
                error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInOrForOfVariableDeclaration(iterationStatement) {
            var variableDeclarationList = iterationStatement.initializer;
            // checkGrammarForInOrForOfStatement will check that there is exactly one declaration.
            if (variableDeclarationList.declarations.length >= 1) {
                var decl = variableDeclarationList.declarations[0];
                checkVariableDeclaration(decl);
            }
        }
        function checkRightHandSideOfForOf(rhsExpression, awaitModifier) {
            var expressionType = checkNonNullExpression(rhsExpression);
            return checkIteratedTypeOrElementType(expressionType, rhsExpression, /*allowStringInput*/ true, awaitModifier !== undefined);
        }
        function checkIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables) {
            if (isTypeAny(inputType)) {
                return inputType;
            }
            return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, /*checkAssignability*/ true) || anyType;
        }
        /**
         * When consuming an iterable type in a for..of, spread, or iterator destructuring assignment
         * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
         * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
         */
        function getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, checkAssignability) {
            var uplevelIteration = languageVersion >= 2 /* ES2015 */;
            var downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
            // Get the iterated type of an `Iterable<T>` or `IterableIterator<T>` only in ES2015
            // or higher, when inside of an async generator or for-await-if, or when
            // downlevelIteration is requested.
            if (uplevelIteration || downlevelIteration || allowAsyncIterables) {
                // We only report errors for an invalid iterable type in ES2015 or higher.
                var iteratedType = getIteratedTypeOfIterable(inputType, uplevelIteration ? errorNode : undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability);
                if (iteratedType || uplevelIteration) {
                    return iteratedType;
                }
            }
            var arrayType = inputType;
            var reportedError = false;
            var hasStringConstituent = false;
            // If strings are permitted, remove any string-like constituents from the array type.
            // This allows us to find other non-string element types from an array unioned with
            // a string.
            if (allowStringInput) {
                if (arrayType.flags & 65536 /* Union */) {
                    // After we remove all types that are StringLike, we will know if there was a string constituent
                    // based on whether the result of filter is a new array.
                    var arrayTypes = inputType.types;
                    var filteredTypes = ts.filter(arrayTypes, function (t) { return !(t.flags & 262178 /* StringLike */); });
                    if (filteredTypes !== arrayTypes) {
                        arrayType = getUnionType(filteredTypes, /*subtypeReduction*/ true);
                    }
                }
                else if (arrayType.flags & 262178 /* StringLike */) {
                    arrayType = neverType;
                }
                hasStringConstituent = arrayType !== inputType;
                if (hasStringConstituent) {
                    if (languageVersion < 1 /* ES5 */) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher);
                            reportedError = true;
                        }
                    }
                    // Now that we've removed all the StringLike types, if no constituents remain, then the entire
                    // arrayOrStringType was a string.
                    if (arrayType.flags & 8192 /* Never */) {
                        return stringType;
                    }
                }
            }
            if (!isArrayLikeType(arrayType)) {
                if (errorNode && !reportedError) {
                    // Which error we report depends on whether we allow strings or if there was a
                    // string constituent. For example, if the input type is number | string, we
                    // want to say that number is not an array type. But if the input was just
                    // number and string input is allowed, we want to say that number is not an
                    // array type or a string type.
                    var diagnostic = !allowStringInput || hasStringConstituent
                        ? downlevelIteration
                            ? ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
                            : ts.Diagnostics.Type_0_is_not_an_array_type
                        : downlevelIteration
                            ? ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
                            : ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
                    error(errorNode, diagnostic, typeToString(arrayType));
                }
                return hasStringConstituent ? stringType : undefined;
            }
            var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */);
            if (hasStringConstituent && arrayElementType) {
                // This is just an optimization for the case where arrayOrStringType is string | string[]
                if (arrayElementType.flags & 262178 /* StringLike */) {
                    return stringType;
                }
                return getUnionType([arrayElementType, stringType], /*subtypeReduction*/ true);
            }
            return arrayElementType;
        }
        /**
         * We want to treat type as an iterable, and get the type it is an iterable of. The iterable
         * must have the following structure (annotated with the names of the variables below):
         *
         *     { // iterable
         *         [Symbol.iterator]: { // iteratorMethod
         *             (): Iterator<T>
         *         }
         *     }
         *
         * For an async iterable, we expect the following structure:
         *
         *     { // iterable
         *         [Symbol.asyncIterator]: { // iteratorMethod
         *             (): AsyncIterator<T>
         *         }
         *     }
         *
         * T is the type we are after. At every level that involves analyzing return types
         * of signatures, we union the return types of all the signatures.
         *
         * Another thing to note is that at any step of this process, we could run into a dead end,
         * meaning either the property is missing, or we run into the anyType. If either of these things
         * happens, we return undefined to signal that we could not find the iterated type. If a property
         * is missing, and the previous step did not result in 'any', then we also give an error if the
         * caller requested it. Then the caller can decide what to do in the case where there is no iterated
         * type. This is different from returning anyType, because that would signify that we have matched the
         * whole pattern and that T (above) is 'any'.
         *
         * For a **for-of** statement, `yield*` (in a normal generator), spread, array
         * destructuring, or normal generator we will only ever look for a `[Symbol.iterator]()`
         * method.
         *
         * For an async generator we will only ever look at the `[Symbol.asyncIterator]()` method.
         *
         * For a **for-await-of** statement or a `yield*` in an async generator we will look for
         * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
         */
        function getIteratedTypeOfIterable(type, errorNode, allowAsyncIterables, allowSyncIterables, checkAssignability) {
            if (isTypeAny(type)) {
                return undefined;
            }
            return mapType(type, getIteratedType);
            function getIteratedType(type) {
                var typeAsIterable = type;
                if (allowAsyncIterables) {
                    if (typeAsIterable.iteratedTypeOfAsyncIterable) {
                        return typeAsIterable.iteratedTypeOfAsyncIterable;
                    }
                    // As an optimization, if the type is an instantiation of the global `AsyncIterable<T>`
                    // or the global `AsyncIterableIterator<T>` then just grab its type argument.
                    if (isReferenceToType(type, getGlobalAsyncIterableType(/*reportErrors*/ false)) ||
                        isReferenceToType(type, getGlobalAsyncIterableIteratorType(/*reportErrors*/ false))) {
                        return typeAsIterable.iteratedTypeOfAsyncIterable = type.typeArguments[0];
                    }
                }
                if (allowSyncIterables) {
                    if (typeAsIterable.iteratedTypeOfIterable) {
                        return typeAsIterable.iteratedTypeOfIterable;
                    }
                    // As an optimization, if the type is an instantiation of the global `Iterable<T>` or
                    // `IterableIterator<T>` then just grab its type argument.
                    if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) ||
                        isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) {
                        return typeAsIterable.iteratedTypeOfIterable = type.typeArguments[0];
                    }
                }
                var asyncMethodType = allowAsyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("asyncIterator"));
                var methodType = asyncMethodType || (allowSyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")));
                if (isTypeAny(methodType)) {
                    return undefined;
                }
                var signatures = methodType && getSignaturesOfType(methodType, 0 /* Call */);
                if (!ts.some(signatures)) {
                    if (errorNode) {
                        error(errorNode, allowAsyncIterables
                            ? ts.Diagnostics.Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
                            : ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
                        // only report on the first error
                        errorNode = undefined;
                    }
                    return undefined;
                }
                var returnType = getUnionType(ts.map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
                var iteratedType = getIteratedTypeOfIterator(returnType, errorNode, /*isAsyncIterator*/ !!asyncMethodType);
                if (checkAssignability && errorNode && iteratedType) {
                    // If `checkAssignability` was specified, we were called from
                    // `checkIteratedTypeOrElementType`. As such, we need to validate that
                    // the type passed in is actually an Iterable.
                    checkTypeAssignableTo(type, asyncMethodType
                        ? createAsyncIterableType(iteratedType)
                        : createIterableType(iteratedType), errorNode);
                }
                return asyncMethodType
                    ? typeAsIterable.iteratedTypeOfAsyncIterable = iteratedType
                    : typeAsIterable.iteratedTypeOfIterable = iteratedType;
            }
        }
        /**
         * This function has very similar logic as getIteratedTypeOfIterable, except that it operates on
         * Iterators instead of Iterables. Here is the structure:
         *
         *  { // iterator
         *      next: { // nextMethod
         *          (): { // nextResult
         *              value: T // nextValue
         *          }
         *      }
         *  }
         *
         * For an async iterator, we expect the following structure:
         *
         *  { // iterator
         *      next: { // nextMethod
         *          (): PromiseLike<{ // nextResult
         *              value: T // nextValue
         *          }>
         *      }
         *  }
         */
        function getIteratedTypeOfIterator(type, errorNode, isAsyncIterator) {
            if (isTypeAny(type)) {
                return undefined;
            }
            var typeAsIterator = type;
            if (isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator) {
                return isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator;
            }
            // As an optimization, if the type is an instantiation of the global `Iterator<T>` (for
            // a non-async iterator) or the global `AsyncIterator<T>` (for an async-iterator) then
            // just grab its type argument.
            var getIteratorType = isAsyncIterator ? getGlobalAsyncIteratorType : getGlobalIteratorType;
            if (isReferenceToType(type, getIteratorType(/*reportErrors*/ false))) {
                return isAsyncIterator
                    ? typeAsIterator.iteratedTypeOfAsyncIterator = type.typeArguments[0]
                    : typeAsIterator.iteratedTypeOfIterator = type.typeArguments[0];
            }
            // Both async and non-async iterators must have a `next` method.
            var nextMethod = getTypeOfPropertyOfType(type, "next");
            if (isTypeAny(nextMethod)) {
                return undefined;
            }
            var nextMethodSignatures = nextMethod ? getSignaturesOfType(nextMethod, 0 /* Call */) : ts.emptyArray;
            if (nextMethodSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, isAsyncIterator
                        ? ts.Diagnostics.An_async_iterator_must_have_a_next_method
                        : ts.Diagnostics.An_iterator_must_have_a_next_method);
                }
                return undefined;
            }
            var nextResult = getUnionType(ts.map(nextMethodSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
            if (isTypeAny(nextResult)) {
                return undefined;
            }
            // For an async iterator, we must get the awaited type of the return type.
            if (isAsyncIterator) {
                nextResult = getAwaitedTypeOfPromise(nextResult, errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property);
                if (isTypeAny(nextResult)) {
                    return undefined;
                }
            }
            var nextValue = nextResult && getTypeOfPropertyOfType(nextResult, "value");
            if (!nextValue) {
                if (errorNode) {
                    error(errorNode, isAsyncIterator
                        ? ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property
                        : ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property);
                }
                return undefined;
            }
            return isAsyncIterator
                ? typeAsIterator.iteratedTypeOfAsyncIterator = nextValue
                : typeAsIterator.iteratedTypeOfIterator = nextValue;
        }
        /**
         * A generator may have a return type of `Iterator<T>`, `Iterable<T>`, or
         * `IterableIterator<T>`. An async generator may have a return type of `AsyncIterator<T>`,
         * `AsyncIterable<T>`, or `AsyncIterableIterator<T>`. This function can be used to extract
         * the iterated type from this return type for contextual typing and verifying signatures.
         */
        function getIteratedTypeOfGenerator(returnType, isAsyncGenerator) {
            if (isTypeAny(returnType)) {
                return undefined;
            }
            return getIteratedTypeOfIterable(returnType, /*errorNode*/ undefined, /*allowAsyncIterables*/ isAsyncGenerator, /*allowSyncIterables*/ !isAsyncGenerator, /*checkAssignability*/ false)
                || getIteratedTypeOfIterator(returnType, /*errorNode*/ undefined, isAsyncGenerator);
        }
        function checkBreakOrContinueStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
            // TODO: Check that target label is valid
        }
        function isGetAccessorWithAnnotatedSetAccessor(node) {
            return node.kind === 153 /* GetAccessor */
                && ts.getEffectiveSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(node.symbol, 154 /* SetAccessor */)) !== undefined;
        }
        function isUnwrappedReturnTypeVoidOrAny(func, returnType) {
            var unwrappedReturnType = (ts.getFunctionFlags(func) & 3 /* AsyncGenerator */) === 2 /* Async */
                ? getPromisedTypeOfPromise(returnType) // Async function
                : returnType; // AsyncGenerator function, Generator function, or normal function
            return unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 1024 /* Void */ | 1 /* Any */);
        }
        function checkReturnStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                var functionBlock = ts.getContainingFunction(node);
                if (!functionBlock) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
                }
            }
            var func = ts.getContainingFunction(node);
            if (func) {
                var signature = getSignatureFromDeclaration(func);
                var returnType = getReturnTypeOfSignature(signature);
                if (strictNullChecks || node.expression || returnType.flags & 8192 /* Never */) {
                    var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
                    var functionFlags = ts.getFunctionFlags(func);
                    if (functionFlags & 1 /* Generator */) {
                        // A generator does not need its return expressions checked against its return type.
                        // Instead, the yield expressions are checked against the element type.
                        // TODO: Check return expressions of generators when return type tracking is added
                        // for generators.
                        return;
                    }
                    if (func.kind === 154 /* SetAccessor */) {
                        if (node.expression) {
                            error(node, ts.Diagnostics.Setters_cannot_return_a_value);
                        }
                    }
                    else if (func.kind === 152 /* Constructor */) {
                        if (node.expression && !checkTypeAssignableTo(exprType, returnType, node)) {
                            error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
                        }
                    }
                    else if (ts.getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func)) {
                        if (functionFlags & 2 /* Async */) {
                            var promisedType = getPromisedTypeOfPromise(returnType);
                            var awaitedType = checkAwaitedType(exprType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                            if (promisedType) {
                                // If the function has a return type, but promisedType is
                                // undefined, an error will be reported in checkAsyncFunctionReturnType
                                // so we don't need to report one here.
                                checkTypeAssignableTo(awaitedType, promisedType, node);
                            }
                        }
                        else {
                            checkTypeAssignableTo(exprType, returnType, node);
                        }
                    }
                }
                else if (func.kind !== 152 /* Constructor */ && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) {
                    // The function has a return type, but the return statement doesn't have an expression.
                    error(node, ts.Diagnostics.Not_all_code_paths_return_a_value);
                }
            }
        }
        function checkWithStatement(node) {
            // Grammar checking for withStatement
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.flags & 16384 /* AwaitContext */) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
                }
            }
            checkExpression(node.expression);
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start;
                var end = node.statement.pos;
                grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any);
            }
        }
        function checkSwitchStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var firstDefaultClause;
            var hasDuplicateDefaultClause = false;
            var expressionType = checkExpression(node.expression);
            var expressionIsLiteral = isLiteralType(expressionType);
            ts.forEach(node.caseBlock.clauses, function (clause) {
                // Grammar check for duplicate default clauses, skip if we already report duplicate default clause
                if (clause.kind === 258 /* DefaultClause */ && !hasDuplicateDefaultClause) {
                    if (firstDefaultClause === undefined) {
                        firstDefaultClause = clause;
                    }
                    else {
                        var sourceFile = ts.getSourceFileOfNode(node);
                        var start = ts.skipTrivia(sourceFile.text, clause.pos);
                        var end = clause.statements.length > 0 ? clause.statements[0].pos : clause.end;
                        grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
                        hasDuplicateDefaultClause = true;
                    }
                }
                if (produceDiagnostics && clause.kind === 257 /* CaseClause */) {
                    var caseClause = clause;
                    // TypeScript 1.0 spec (April 2014): 5.9
                    // In a 'switch' statement, each 'case' expression must be of a type that is comparable
                    // to or from the type of the 'switch' expression.
                    var caseType = checkExpression(caseClause.expression);
                    var caseIsLiteral = isLiteralType(caseType);
                    var comparedExpressionType = expressionType;
                    if (!caseIsLiteral || !expressionIsLiteral) {
                        caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
                        comparedExpressionType = getBaseTypeOfLiteralType(expressionType);
                    }
                    if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) {
                        // expressionType is not comparable to caseType, try the reversed check and report errors if it fails
                        checkTypeComparableTo(caseType, comparedExpressionType, caseClause.expression, /*headMessage*/ undefined);
                    }
                }
                ts.forEach(clause.statements, checkSourceElement);
            });
            if (node.caseBlock.locals) {
                registerForUnusedIdentifiersCheck(node.caseBlock);
            }
        }
        function checkLabeledStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                ts.findAncestor(node.parent, function (current) {
                    if (ts.isFunctionLike(current)) {
                        return "quit";
                    }
                    if (current.kind === 222 /* LabeledStatement */ && current.label.escapedText === node.label.escapedText) {
                        var sourceFile = ts.getSourceFileOfNode(node);
                        grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNodeFromSourceText(sourceFile.text, node.label));
                        return true;
                    }
                });
            }
            // ensure that label is unique
            checkSourceElement(node.statement);
        }
        function checkThrowStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.expression === undefined) {
                    grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here);
                }
            }
            if (node.expression) {
                checkExpression(node.expression);
            }
        }
        function checkTryStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkBlock(node.tryBlock);
            var catchClause = node.catchClause;
            if (catchClause) {
                // Grammar checking
                if (catchClause.variableDeclaration) {
                    if (catchClause.variableDeclaration.type) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.type, ts.Diagnostics.Catch_clause_variable_cannot_have_a_type_annotation);
                    }
                    else if (catchClause.variableDeclaration.initializer) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
                    }
                    else {
                        var blockLocals_1 = catchClause.block.locals;
                        if (blockLocals_1) {
                            ts.forEachKey(catchClause.locals, function (caughtName) {
                                var blockLocal = blockLocals_1.get(caughtName);
                                if (blockLocal && (blockLocal.flags & 2 /* BlockScopedVariable */) !== 0) {
                                    grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName);
                                }
                            });
                        }
                    }
                }
                checkBlock(catchClause.block);
            }
            if (node.finallyBlock) {
                checkBlock(node.finallyBlock);
            }
        }
        function checkIndexConstraints(type) {
            var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */);
            var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */);
            var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
            var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
            if (stringIndexType || numberIndexType) {
                ts.forEach(getPropertiesOfObjectType(type), function (prop) {
                    var propType = getTypeOfSymbol(prop);
                    checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                    checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                });
                if (getObjectFlags(type) & 1 /* Class */ && ts.isClassLike(type.symbol.valueDeclaration)) {
                    var classDeclaration = type.symbol.valueDeclaration;
                    for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        // Only process instance properties with computed names here.
                        // Static properties cannot be in conflict with indexers,
                        // and properties with literal names were already checked.
                        if (!ts.hasModifier(member, 32 /* Static */) && ts.hasDynamicName(member)) {
                            var propType = getTypeOfSymbol(member.symbol);
                            checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                            checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                        }
                    }
                }
            }
            var errorNode;
            if (stringIndexType && numberIndexType) {
                errorNode = declaredNumberIndexer || declaredStringIndexer;
                // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer
                if (!errorNode && (getObjectFlags(type) & 2 /* Interface */)) {
                    var someBaseTypeHasBothIndexers = ts.forEach(getBaseTypes(type), function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); });
                    errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0];
                }
            }
            if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) {
                error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType));
            }
            function checkIndexConstraintForProperty(prop, propertyType, containingType, indexDeclaration, indexType, indexKind) {
                if (!indexType) {
                    return;
                }
                var propDeclaration = prop.valueDeclaration;
                // index is numeric and property name is not valid numeric literal
                if (indexKind === 1 /* Number */ && !(propDeclaration ? isNumericName(ts.getNameOfDeclaration(propDeclaration)) : isNumericLiteralName(prop.escapedName))) {
                    return;
                }
                // perform property check if property or indexer is declared in 'type'
                // this allows us to rule out cases when both property and indexer are inherited from the base class
                var errorNode;
                if (propDeclaration &&
                    (propDeclaration.kind === 194 /* BinaryExpression */ ||
                        ts.getNameOfDeclaration(propDeclaration).kind === 144 /* ComputedPropertyName */ ||
                        prop.parent === containingType.symbol)) {
                    errorNode = propDeclaration;
                }
                else if (indexDeclaration) {
                    errorNode = indexDeclaration;
                }
                else if (getObjectFlags(containingType) & 2 /* Interface */) {
                    // for interfaces property and indexer might be inherited from different bases
                    // check if any base class already has both property and indexer.
                    // check should be performed only if 'type' is the first type that brings property\indexer together
                    var someBaseClassHasBothPropertyAndIndexer = ts.forEach(getBaseTypes(containingType), function (base) { return getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind); });
                    errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : containingType.symbol.declarations[0];
                }
                if (errorNode && !isTypeAssignableTo(propertyType, indexType)) {
                    var errorMessage = indexKind === 0 /* String */
                        ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2
                        : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2;
                    error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType));
                }
            }
        }
        function checkTypeNameIsReserved(name, message) {
            // TS 1.0 spec (April 2014): 3.6.1
            // The predefined type keywords are reserved and cannot be used as names of user defined types.
            switch (name.escapedText) {
                case "any":
                case "number":
                case "boolean":
                case "string":
                case "symbol":
                case "void":
                case "object":
                    error(name, message, name.escapedText);
            }
        }
        /**
         * Check each type parameter and check that type parameters have no duplicate type parameter declarations
         */
        function checkTypeParameters(typeParameterDeclarations) {
            if (typeParameterDeclarations) {
                var seenDefault = false;
                for (var i = 0; i < typeParameterDeclarations.length; i++) {
                    var node = typeParameterDeclarations[i];
                    checkTypeParameter(node);
                    if (produceDiagnostics) {
                        if (node.default) {
                            seenDefault = true;
                        }
                        else if (seenDefault) {
                            error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
                        }
                        for (var j = 0; j < i; j++) {
                            if (typeParameterDeclarations[j].symbol === node.symbol) {
                                error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name));
                            }
                        }
                    }
                }
            }
        }
        /** Check that type parameter lists are identical across multiple declarations */
        function checkTypeParameterListsIdentical(symbol) {
            if (symbol.declarations.length === 1) {
                return;
            }
            var links = getSymbolLinks(symbol);
            if (!links.typeParametersChecked) {
                links.typeParametersChecked = true;
                var declarations = getClassOrInterfaceDeclarationsOfSymbol(symbol);
                if (declarations.length <= 1) {
                    return;
                }
                var type = getDeclaredTypeOfSymbol(symbol);
                if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) {
                    // Report an error on every conflicting declaration.
                    var name = symbolToString(symbol);
                    for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) {
                        var declaration = declarations_5[_i];
                        error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name);
                    }
                }
            }
        }
        function areTypeParametersIdentical(declarations, typeParameters) {
            var maxTypeArgumentCount = ts.length(typeParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
            for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) {
                var declaration = declarations_6[_i];
                // If this declaration has too few or too many type parameters, we report an error
                var numTypeParameters = ts.length(declaration.typeParameters);
                if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) {
                    return false;
                }
                for (var i = 0; i < numTypeParameters; i++) {
                    var source = declaration.typeParameters[i];
                    var target = typeParameters[i];
                    // If the type parameter node does not have the same as the resolved type
                    // parameter at this position, we report an error.
                    if (source.name.escapedText !== target.symbol.escapedName) {
                        return false;
                    }
                    // If the type parameter node does not have an identical constraint as the resolved
                    // type parameter at this position, we report an error.
                    var sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
                    var targetConstraint = getConstraintFromTypeParameter(target);
                    if ((sourceConstraint || targetConstraint) &&
                        (!sourceConstraint || !targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint))) {
                        return false;
                    }
                    // If the type parameter node has a default and it is not identical to the default
                    // for the type parameter at this position, we report an error.
                    var sourceDefault = source.default && getTypeFromTypeNode(source.default);
                    var targetDefault = getDefaultFromTypeParameter(target);
                    if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function checkClassExpression(node) {
            checkClassLikeDeclaration(node);
            checkNodeDeferred(node);
            return getTypeOfSymbol(getSymbolOfNode(node));
        }
        function checkClassExpressionDeferred(node) {
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassDeclaration(node) {
            if (!node.name && !ts.hasModifier(node, 512 /* Default */)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
            }
            checkClassLikeDeclaration(node);
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassLikeDeclaration(node) {
            checkGrammarClassLikeDeclaration(node);
            checkDecorators(node);
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithCapturedNewTargetVariable(node, node.name);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
            checkTypeParameters(node.typeParameters);
            checkExportsOnMergedDeclarations(node);
            var symbol = getSymbolOfNode(node);
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeWithThis = getTypeWithThisArgument(type);
            var staticType = getTypeOfSymbol(symbol);
            checkTypeParameterListsIdentical(symbol);
            checkClassForDuplicateDeclarations(node);
            // Only check for reserved static identifiers on non-ambient context.
            if (!ts.isInAmbientContext(node)) {
                checkClassForStaticPropertyNameConflicts(node);
            }
            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
            if (baseTypeNode) {
                if (languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(baseTypeNode.parent, 1 /* Extends */);
                }
                var baseTypes = getBaseTypes(type);
                if (baseTypes.length && produceDiagnostics) {
                    var baseType_1 = baseTypes[0];
                    var baseConstructorType = getBaseConstructorTypeOfClass(type);
                    var staticBaseType = getApparentType(baseConstructorType);
                    checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
                    checkSourceElement(baseTypeNode.expression);
                    if (ts.some(baseTypeNode.typeArguments)) {
                        ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                        for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); _i < _a.length; _i++) {
                            var constructor = _a[_i];
                            if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments)) {
                                break;
                            }
                        }
                    }
                    checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType_1, type.thisType), node.name || node, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1);
                    checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
                    if (baseConstructorType.flags & 540672 /* TypeVariable */ && !isMixinConstructorType(staticType)) {
                        error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
                    }
                    if (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */) && !(baseConstructorType.flags & 540672 /* TypeVariable */)) {
                        // When the static base type is a "class-like" constructor function (but not actually a class), we verify
                        // that all instantiated base constructor signatures return the same type. We can simply compare the type
                        // references (as opposed to checking the structure of the types) because elsewhere we have already checked
                        // that the base type is a class or interface type (and not, for example, an anonymous object type).
                        var constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode);
                        if (ts.forEach(constructors, function (sig) { return getReturnTypeOfSignature(sig) !== baseType_1; })) {
                            error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type);
                        }
                    }
                    checkKindsOfPropertyMemberOverrides(type, baseType_1);
                }
            }
            var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(node);
            if (implementedTypeNodes) {
                for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) {
                    var typeRefNode = implementedTypeNodes_1[_b];
                    if (!ts.isEntityNameExpression(typeRefNode.expression)) {
                        error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments);
                    }
                    checkTypeReferenceNode(typeRefNode);
                    if (produceDiagnostics) {
                        var t = getTypeFromTypeNode(typeRefNode);
                        if (t !== unknownType) {
                            if (isValidBaseType(t)) {
                                checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(t, type.thisType), node.name || node, ts.Diagnostics.Class_0_incorrectly_implements_interface_1);
                            }
                            else {
                                error(typeRefNode, ts.Diagnostics.A_class_may_only_implement_another_class_or_interface);
                            }
                        }
                    }
                }
            }
            if (produceDiagnostics) {
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
            }
        }
        function checkBaseTypeAccessibility(type, node) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length) {
                var declaration = signatures[0].declaration;
                if (declaration && ts.hasModifier(declaration, 8 /* Private */)) {
                    var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol);
                    if (!isNodeWithinClass(node, typeClassDeclaration)) {
                        error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol));
                    }
                }
            }
        }
        function getTargetSymbol(s) {
            // if symbol is instantiated its flags are not copied from the 'target'
            // so we'll need to get back original 'target' symbol to work with correct set of flags
            return ts.getCheckFlags(s) & 1 /* Instantiated */ ? s.target : s;
        }
        function getClassLikeDeclarationOfSymbol(symbol) {
            return ts.forEach(symbol.declarations, function (d) { return ts.isClassLike(d) ? d : undefined; });
        }
        function getClassOrInterfaceDeclarationsOfSymbol(symbol) {
            return ts.filter(symbol.declarations, function (d) {
                return d.kind === 229 /* ClassDeclaration */ || d.kind === 230 /* InterfaceDeclaration */;
            });
        }
        function checkKindsOfPropertyMemberOverrides(type, baseType) {
            // TypeScript 1.0 spec (April 2014): 8.2.3
            // A derived class inherits all members from its base class it doesn't override.
            // Inheritance means that a derived class implicitly contains all non - overridden members of the base class.
            // Both public and private property members are inherited, but only public property members can be overridden.
            // A property member in a derived class is said to override a property member in a base class
            // when the derived class property member has the same name and kind(instance or static)
            // as the base class property member.
            // The type of an overriding property member must be assignable(section 3.8.4)
            // to the type of the overridden property member, or otherwise a compile - time error occurs.
            // Base class instance member functions can be overridden by derived class instance member functions,
            // but not by other kinds of members.
            // Base class instance member variables and accessors can be overridden by
            // derived class instance member variables and accessors, but not by other kinds of members.
            // NOTE: assignability is checked in checkClassDeclaration
            var baseProperties = getPropertiesOfType(baseType);
            for (var _i = 0, baseProperties_1 = baseProperties; _i < baseProperties_1.length; _i++) {
                var baseProperty = baseProperties_1[_i];
                var base = getTargetSymbol(baseProperty);
                if (base.flags & 4194304 /* Prototype */) {
                    continue;
                }
                var derived = getTargetSymbol(getPropertyOfObjectType(type, base.escapedName));
                var baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base);
                ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
                if (derived) {
                    // In order to resolve whether the inherited method was overridden in the base class or not,
                    // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
                    // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
                    if (derived === base) {
                        // derived class inherits base without override/redeclaration
                        var derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol);
                        // It is an error to inherit an abstract member without implementing it or being declared abstract.
                        // If there is no declaration for the derived class (as in the case of class expressions),
                        // then the class cannot be declared abstract.
                        if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) {
                            if (derivedClassDecl.kind === 199 /* ClassExpression */) {
                                error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType));
                            }
                            else {
                                error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType));
                            }
                        }
                    }
                    else {
                        // derived overrides base.
                        var derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived);
                        if (baseDeclarationFlags & 8 /* Private */ || derivedDeclarationFlags & 8 /* Private */) {
                            // either base or derived property is private - not override, skip it
                            continue;
                        }
                        if (isMethodLike(base) && isMethodLike(derived) || base.flags & 98308 /* PropertyOrAccessor */ && derived.flags & 98308 /* PropertyOrAccessor */) {
                            // method is overridden with method or property/accessor is overridden with property/accessor - correct case
                            continue;
                        }
                        var errorMessage = void 0;
                        if (isMethodLike(base)) {
                            if (derived.flags & 98304 /* Accessor */) {
                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
                            }
                            else {
                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property;
                            }
                        }
                        else if (base.flags & 4 /* Property */) {
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                        }
                        else {
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                        }
                        error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
                    }
                }
            }
        }
        function checkInheritedPropertiesAreIdentical(type, typeNode) {
            var baseTypes = getBaseTypes(type);
            if (baseTypes.length < 2) {
                return true;
            }
            var seen = ts.createUnderscoreEscapedMap();
            ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen.set(p.escapedName, { prop: p, containingType: type }); });
            var ok = true;
            for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) {
                var base = baseTypes_2[_i];
                var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) {
                    var prop = properties_8[_a];
                    var existing = seen.get(prop.escapedName);
                    if (!existing) {
                        seen.set(prop.escapedName, { prop: prop, containingType: base });
                    }
                    else {
                        var isInheritedProperty = existing.containingType !== type;
                        if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
                            ok = false;
                            var typeName1 = typeToString(existing.containingType);
                            var typeName2 = typeToString(base);
                            var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2);
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo));
                        }
                    }
                }
            }
            return ok;
        }
        function checkInterfaceDeclaration(node) {
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
            checkTypeParameters(node.typeParameters);
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0);
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                checkTypeParameterListsIdentical(symbol);
                // Only check this symbol once
                var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 230 /* InterfaceDeclaration */);
                if (node === firstInterfaceDecl) {
                    var type = getDeclaredTypeOfSymbol(symbol);
                    var typeWithThis = getTypeWithThisArgument(type);
                    // run subsequent checks only if first set succeeded
                    if (checkInheritedPropertiesAreIdentical(type, node.name)) {
                        for (var _i = 0, _a = getBaseTypes(type); _i < _a.length; _i++) {
                            var baseType = _a[_i];
                            checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1);
                        }
                        checkIndexConstraints(type);
                    }
                }
                checkObjectTypeForDuplicateDeclarations(node);
            }
            ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) {
                if (!ts.isEntityNameExpression(heritageElement.expression)) {
                    error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments);
                }
                checkTypeReferenceNode(heritageElement);
            });
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                checkTypeForDuplicateIndexSignatures(node);
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkTypeAliasDeclaration(node) {
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            checkTypeParameters(node.typeParameters);
            checkSourceElement(node.type);
            registerForUnusedIdentifiersCheck(node);
        }
        function computeEnumMemberValues(node) {
            var nodeLinks = getNodeLinks(node);
            if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) {
                nodeLinks.flags |= 16384 /* EnumValuesComputed */;
                var autoValue = 0;
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    var value = computeMemberValue(member, autoValue);
                    getNodeLinks(member).enumMemberValue = value;
                    autoValue = typeof value === "number" ? value + 1 : undefined;
                }
            }
        }
        function computeMemberValue(member, autoValue) {
            if (isComputedNonLiteralName(member.name)) {
                error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
            }
            else {
                var text = ts.getTextOfPropertyName(member.name);
                if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
                    error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
                }
            }
            if (member.initializer) {
                return computeConstantValue(member);
            }
            // In ambient enum declarations that specify no const modifier, enum member declarations that omit
            // a value are considered computed members (as opposed to having auto-incremented values).
            if (ts.isInAmbientContext(member.parent) && !ts.isConst(member.parent)) {
                return undefined;
            }
            // If the member declaration specifies no value, the member is considered a constant enum member.
            // If the member is the first member in the enum declaration, it is assigned the value zero.
            // Otherwise, it is assigned the value of the immediately preceding member plus one, and an error
            // occurs if the immediately preceding member is not a constant enum member.
            if (autoValue !== undefined) {
                return autoValue;
            }
            error(member.name, ts.Diagnostics.Enum_member_must_have_initializer);
            return undefined;
        }
        function computeConstantValue(member) {
            var enumKind = getEnumKind(getSymbolOfNode(member.parent));
            var isConstEnum = ts.isConst(member.parent);
            var initializer = member.initializer;
            var value = enumKind === 1 /* Literal */ && !isLiteralEnumMember(member) ? undefined : evaluate(initializer);
            if (value !== undefined) {
                if (isConstEnum && typeof value === "number" && !isFinite(value)) {
                    error(initializer, isNaN(value) ?
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN :
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
                }
            }
            else if (enumKind === 1 /* Literal */) {
                error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members);
                return 0;
            }
            else if (isConstEnum) {
                error(initializer, ts.Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
            }
            else if (ts.isInAmbientContext(member.parent)) {
                error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
            }
            else {
                // Only here do we need to check that the initializer is assignable to the enum type.
                checkTypeAssignableTo(checkExpression(initializer), getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
            }
            return value;
            function evaluate(expr) {
                switch (expr.kind) {
                    case 192 /* PrefixUnaryExpression */:
                        var value_1 = evaluate(expr.operand);
                        if (typeof value_1 === "number") {
                            switch (expr.operator) {
                                case 37 /* PlusToken */: return value_1;
                                case 38 /* MinusToken */: return -value_1;
                                case 52 /* TildeToken */: return ~value_1;
                            }
                        }
                        break;
                    case 194 /* BinaryExpression */:
                        var left = evaluate(expr.left);
                        var right = evaluate(expr.right);
                        if (typeof left === "number" && typeof right === "number") {
                            switch (expr.operatorToken.kind) {
                                case 49 /* BarToken */: return left | right;
                                case 48 /* AmpersandToken */: return left & right;
                                case 46 /* GreaterThanGreaterThanToken */: return left >> right;
                                case 47 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
                                case 45 /* LessThanLessThanToken */: return left << right;
                                case 50 /* CaretToken */: return left ^ right;
                                case 39 /* AsteriskToken */: return left * right;
                                case 41 /* SlashToken */: return left / right;
                                case 37 /* PlusToken */: return left + right;
                                case 38 /* MinusToken */: return left - right;
                                case 42 /* PercentToken */: return left % right;
                            }
                        }
                        break;
                    case 9 /* StringLiteral */:
                        return expr.text;
                    case 8 /* NumericLiteral */:
                        checkGrammarNumericLiteral(expr);
                        return +expr.text;
                    case 185 /* ParenthesizedExpression */:
                        return evaluate(expr.expression);
                    case 71 /* Identifier */:
                        return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), expr.escapedText);
                    case 180 /* ElementAccessExpression */:
                    case 179 /* PropertyAccessExpression */:
                        var ex = expr;
                        if (isConstantMemberAccess(ex)) {
                            var type = getTypeOfExpression(ex.expression);
                            if (type.symbol && type.symbol.flags & 384 /* Enum */) {
                                var name = void 0;
                                if (ex.kind === 179 /* PropertyAccessExpression */) {
                                    name = ex.name.escapedText;
                                }
                                else {
                                    var argument = ex.argumentExpression;
                                    ts.Debug.assert(ts.isLiteralExpression(argument));
                                    name = ts.escapeLeadingUnderscores(argument.text);
                                }
                                return evaluateEnumMember(expr, type.symbol, name);
                            }
                        }
                        break;
                }
                return undefined;
            }
            function evaluateEnumMember(expr, enumSymbol, name) {
                var memberSymbol = enumSymbol.exports.get(name);
                if (memberSymbol) {
                    var declaration = memberSymbol.valueDeclaration;
                    if (declaration !== member) {
                        if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
                            return getNodeLinks(declaration).enumMemberValue;
                        }
                        error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
                        return 0;
                    }
                }
                return undefined;
            }
        }
        function isConstantMemberAccess(node) {
            return node.kind === 71 /* Identifier */ ||
                node.kind === 179 /* PropertyAccessExpression */ && isConstantMemberAccess(node.expression) ||
                node.kind === 180 /* ElementAccessExpression */ && isConstantMemberAccess(node.expression) &&
                    node.argumentExpression.kind === 9 /* StringLiteral */;
        }
        function checkEnumDeclaration(node) {
            if (!produceDiagnostics) {
                return;
            }
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0);
            checkCollisionWithCapturedThisVariable(node, node.name);
            checkCollisionWithCapturedNewTargetVariable(node, node.name);
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkExportsOnMergedDeclarations(node);
            computeEnumMemberValues(node);
            var enumIsConst = ts.isConst(node);
            if (compilerOptions.isolatedModules && enumIsConst && ts.isInAmbientContext(node)) {
                error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided);
            }
            // Spec 2014 - Section 9.3:
            // It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
            // and when an enum type has multiple declarations, only one declaration is permitted to omit a value
            // for the first member.
            //
            // Only perform this check once per symbol
            var enumSymbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind);
            if (node === firstDeclaration) {
                if (enumSymbol.declarations.length > 1) {
                    // check that const is placed\omitted on all enum declarations
                    ts.forEach(enumSymbol.declarations, function (decl) {
                        if (ts.isConstEnumDeclaration(decl) !== enumIsConst) {
                            error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
                        }
                    });
                }
                var seenEnumMissingInitialInitializer_1 = false;
                ts.forEach(enumSymbol.declarations, function (declaration) {
                    // return true if we hit a violation of the rule, false otherwise
                    if (declaration.kind !== 232 /* EnumDeclaration */) {
                        return false;
                    }
                    var enumDeclaration = declaration;
                    if (!enumDeclaration.members.length) {
                        return false;
                    }
                    var firstEnumMember = enumDeclaration.members[0];
                    if (!firstEnumMember.initializer) {
                        if (seenEnumMissingInitialInitializer_1) {
                            error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
                        }
                        else {
                            seenEnumMissingInitialInitializer_1 = true;
                        }
                    }
                });
            }
        }
        function getFirstNonAmbientClassOrFunctionDeclaration(symbol) {
            var declarations = symbol.declarations;
            for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) {
                var declaration = declarations_7[_i];
                if ((declaration.kind === 229 /* ClassDeclaration */ ||
                    (declaration.kind === 228 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) &&
                    !ts.isInAmbientContext(declaration)) {
                    return declaration;
                }
            }
            return undefined;
        }
        function inSameLexicalScope(node1, node2) {
            var container1 = ts.getEnclosingBlockScopeContainer(node1);
            var container2 = ts.getEnclosingBlockScopeContainer(node2);
            if (isGlobalSourceFile(container1)) {
                return isGlobalSourceFile(container2);
            }
            else if (isGlobalSourceFile(container2)) {
                return false;
            }
            else {
                return container1 === container2;
            }
        }
        function checkModuleDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking
                var isGlobalAugmentation = ts.isGlobalScopeAugmentation(node);
                var inAmbientContext = ts.isInAmbientContext(node);
                if (isGlobalAugmentation && !inAmbientContext) {
                    error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
                }
                var isAmbientExternalModule = ts.isAmbientModule(node);
                var contextErrorMessage = isAmbientExternalModule
                    ? ts.Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
                    : ts.Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
                if (checkGrammarModuleElementContext(node, contextErrorMessage)) {
                    // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors.
                    return;
                }
                if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) {
                    if (!inAmbientContext && node.name.kind === 9 /* StringLiteral */) {
                        grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names);
                    }
                }
                if (ts.isIdentifier(node.name)) {
                    checkCollisionWithCapturedThisVariable(node, node.name);
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                }
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                // The following checks only apply on a non-ambient instantiated module declaration.
                if (symbol.flags & 512 /* ValueModule */
                    && symbol.declarations.length > 1
                    && !inAmbientContext
                    && isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) {
                    var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
                    if (firstNonAmbientClassOrFunc) {
                        if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged);
                        }
                        else if (node.pos < firstNonAmbientClassOrFunc.pos) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged);
                        }
                    }
                    // if the module merges with a class declaration in the same lexical scope,
                    // we need to track this to ensure the correct emit.
                    var mergedClass = ts.getDeclarationOfKind(symbol, 229 /* ClassDeclaration */);
                    if (mergedClass &&
                        inSameLexicalScope(node, mergedClass)) {
                        getNodeLinks(node).flags |= 32768 /* LexicalModuleMergesWithClass */;
                    }
                }
                if (isAmbientExternalModule) {
                    if (ts.isExternalModuleAugmentation(node)) {
                        // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module)
                        // otherwise we'll be swamped in cascading errors.
                        // We can detect if augmentation was applied using following rules:
                        // - augmentation for a global scope is always applied
                        // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module).
                        var checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & 33554432 /* Transient */);
                        if (checkBody && node.body) {
                            // body of ambient external module is always a module block
                            for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) {
                                var statement = _a[_i];
                                checkModuleAugmentationElement(statement, isGlobalAugmentation);
                            }
                        }
                    }
                    else if (isGlobalSourceFile(node.parent)) {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) {
                            error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name);
                        }
                    }
                    else {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else {
                            // Node is not an augmentation and is not located on the script level.
                            // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
                            error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
                        }
                    }
                }
            }
            if (node.body) {
                checkSourceElement(node.body);
                if (!ts.isGlobalScopeAugmentation(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkModuleAugmentationElement(node, isGlobalAugmentation) {
            switch (node.kind) {
                case 208 /* VariableStatement */:
                    // error each individual name in variable statement instead of marking the entire variable statement
                    for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        checkModuleAugmentationElement(decl, isGlobalAugmentation);
                    }
                    break;
                case 243 /* ExportAssignment */:
                case 244 /* ExportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations);
                    break;
                case 237 /* ImportEqualsDeclaration */:
                case 238 /* ImportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module);
                    break;
                case 176 /* BindingElement */:
                case 226 /* VariableDeclaration */:
                    var name = node.name;
                    if (ts.isBindingPattern(name)) {
                        for (var _b = 0, _c = name.elements; _b < _c.length; _b++) {
                            var el = _c[_b];
                            // mark individual names in binding pattern
                            checkModuleAugmentationElement(el, isGlobalAugmentation);
                        }
                        break;
                    }
                // falls through
                case 229 /* ClassDeclaration */:
                case 232 /* EnumDeclaration */:
                case 228 /* FunctionDeclaration */:
                case 230 /* InterfaceDeclaration */:
                case 233 /* ModuleDeclaration */:
                case 231 /* TypeAliasDeclaration */:
                    if (isGlobalAugmentation) {
                        return;
                    }
                    var symbol = getSymbolOfNode(node);
                    if (symbol) {
                        // module augmentations cannot introduce new names on the top level scope of the module
                        // this is done it two steps
                        // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error
                        // 2. main check - report error if value declaration of the parent symbol is module augmentation)
                        var reportError = !(symbol.flags & 33554432 /* Transient */);
                        if (!reportError) {
                            // symbol should not originate in augmentation
                            reportError = ts.isExternalModuleAugmentation(symbol.parent.declarations[0]);
                        }
                    }
                    break;
            }
        }
        function getFirstIdentifier(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return node;
                case 143 /* QualifiedName */:
                    do {
                        node = node.left;
                    } while (node.kind !== 71 /* Identifier */);
                    return node;
                case 179 /* PropertyAccessExpression */:
                    do {
                        node = node.expression;
                    } while (node.kind !== 71 /* Identifier */);
                    return node;
            }
        }
        function checkExternalImportOrExportDeclaration(node) {
            var moduleName = ts.getExternalModuleName(node);
            if (!ts.nodeIsMissing(moduleName) && moduleName.kind !== 9 /* StringLiteral */) {
                error(moduleName, ts.Diagnostics.String_literal_expected);
                return false;
            }
            var inAmbientExternalModule = node.parent.kind === 234 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
            if (node.parent.kind !== 265 /* SourceFile */ && !inAmbientExternalModule) {
                error(moduleName, node.kind === 244 /* ExportDeclaration */ ?
                    ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace :
                    ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module);
                return false;
            }
            if (inAmbientExternalModule && ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(moduleName))) {
                // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration
                // no need to do this again.
                if (!isTopLevelInExternalModuleAugmentation(node)) {
                    // TypeScript 1.0 spec (April 2013): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
                    // other external modules only through top - level external module names.
                    // Relative external module names are not permitted.
                    error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name);
                    return false;
                }
            }
            return true;
        }
        function checkAliasSymbol(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            if (target !== unknownSymbol) {
                // For external modules symbol represent local symbol for an alias.
                // This local symbol will merge any other local declarations (excluding other aliases)
                // and symbol.flags will contains combined representation for all merged declaration.
                // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
                // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
                // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
                var excludedMeanings = (symbol.flags & (107455 /* Value */ | 1048576 /* ExportValue */) ? 107455 /* Value */ : 0) |
                    (symbol.flags & 793064 /* Type */ ? 793064 /* Type */ : 0) |
                    (symbol.flags & 1920 /* Namespace */ ? 1920 /* Namespace */ : 0);
                if (target.flags & excludedMeanings) {
                    var message = node.kind === 246 /* ExportSpecifier */ ?
                        ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
                        ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
                    error(node, message, symbolToString(symbol));
                }
                // Don't allow to re-export something with no value side when `--isolatedModules` is set.
                if (compilerOptions.isolatedModules
                    && node.kind === 246 /* ExportSpecifier */
                    && !(target.flags & 107455 /* Value */)
                    && !ts.isInAmbientContext(node)) {
                    error(node, ts.Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
                }
            }
        }
        function checkImportBinding(node) {
            checkCollisionWithCapturedThisVariable(node, node.name);
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkAliasSymbol(node);
        }
        function checkImportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers);
            }
            if (checkExternalImportOrExportDeclaration(node)) {
                var importClause = node.importClause;
                if (importClause) {
                    if (importClause.name) {
                        checkImportBinding(importClause);
                    }
                    if (importClause.namedBindings) {
                        if (importClause.namedBindings.kind === 240 /* NamespaceImport */) {
                            checkImportBinding(importClause.namedBindings);
                        }
                        else {
                            ts.forEach(importClause.namedBindings.elements, checkImportBinding);
                        }
                    }
                }
            }
        }
        function checkImportEqualsDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            checkGrammarDecorators(node) || checkGrammarModifiers(node);
            if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
                checkImportBinding(node);
                if (ts.hasModifier(node, 1 /* Export */)) {
                    markExportAsReferenced(node);
                }
                if (ts.isInternalModuleImportEqualsDeclaration(node)) {
                    var target = resolveAlias(getSymbolOfNode(node));
                    if (target !== unknownSymbol) {
                        if (target.flags & 107455 /* Value */) {
                            // Target is a value symbol, check that it is not hidden by a local declaration with the same name
                            var moduleName = getFirstIdentifier(node.moduleReference);
                            if (!(resolveEntityName(moduleName, 107455 /* Value */ | 1920 /* Namespace */).flags & 1920 /* Namespace */)) {
                                error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
                            }
                        }
                        if (target.flags & 793064 /* Type */) {
                            checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
                        }
                    }
                }
                else {
                    if (modulekind >= ts.ModuleKind.ES2015 && !ts.isInAmbientContext(node)) {
                        // Import equals declaration is deprecated in es6 or above
                        grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
                    }
                }
            }
        }
        function checkExportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) {
                // If we hit an export in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers);
            }
            if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
                if (node.exportClause) {
                    // export { x, y }
                    // export { x, y } from "foo"
                    ts.forEach(node.exportClause.elements, checkExportSpecifier);
                    var inAmbientExternalModule = node.parent.kind === 234 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
                    var inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === 234 /* ModuleBlock */ &&
                        !node.moduleSpecifier && ts.isInAmbientContext(node);
                    if (node.parent.kind !== 265 /* SourceFile */ && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
                        error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
                    }
                }
                else {
                    // export * from "foo"
                    var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
                    if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
                        error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
                    }
                    if (modulekind !== ts.ModuleKind.System && modulekind !== ts.ModuleKind.ES2015 && modulekind !== ts.ModuleKind.ESNext) {
                        checkExternalEmitHelpers(node, 32768 /* ExportStar */);
                    }
                }
            }
        }
        function checkGrammarModuleElementContext(node, errorMessage) {
            var isInAppropriateContext = node.parent.kind === 265 /* SourceFile */ || node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 233 /* ModuleDeclaration */;
            if (!isInAppropriateContext) {
                grammarErrorOnFirstToken(node, errorMessage);
            }
            return !isInAppropriateContext;
        }
        function checkExportSpecifier(node) {
            checkAliasSymbol(node);
            if (!node.parent.parent.moduleSpecifier) {
                var exportedName = node.propertyName || node.name;
                // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
                var symbol = resolveName(exportedName, exportedName.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, 
                /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
                    error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName));
                }
                else {
                    markExportAsReferenced(node);
                }
            }
        }
        function checkExportAssignment(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) {
                // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            var container = node.parent.kind === 265 /* SourceFile */ ? node.parent : node.parent.parent;
            if (container.kind === 233 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                if (node.isExportEquals) {
                    error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
                }
                else {
                    error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                }
                return;
            }
            // Grammar checking
            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
            }
            if (node.expression.kind === 71 /* Identifier */) {
                markExportAsReferenced(node);
            }
            else {
                checkExpressionCached(node.expression);
            }
            checkExternalModuleExports(container);
            if (ts.isInAmbientContext(node) && !ts.isEntityNameExpression(node.expression)) {
                grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
            }
            if (node.isExportEquals && !ts.isInAmbientContext(node)) {
                if (modulekind >= ts.ModuleKind.ES2015) {
                    // export assignment is not supported in es6 modules
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
                }
                else if (modulekind === ts.ModuleKind.System) {
                    // system modules does not support export assignment
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
                }
            }
        }
        function hasExportedMembers(moduleSymbol) {
            return ts.forEachEntry(moduleSymbol.exports, function (_, id) { return id !== "export="; });
        }
        function checkExternalModuleExports(node) {
            var moduleSymbol = getSymbolOfNode(node);
            var links = getSymbolLinks(moduleSymbol);
            if (!links.exportsChecked) {
                var exportEqualsSymbol = moduleSymbol.exports.get("export=");
                if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) {
                    var declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration;
                    if (!isTopLevelInExternalModuleAugmentation(declaration)) {
                        error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
                    }
                }
                // Checks for export * conflicts
                var exports = getExportsOfModule(moduleSymbol);
                exports && exports.forEach(function (_a, id) {
                    var declarations = _a.declarations, flags = _a.flags;
                    if (id === "__export") {
                        return;
                    }
                    // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
                    // (TS Exceptions: namespaces, function overloads, enums, and interfaces)
                    if (flags & (1920 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) {
                        return;
                    }
                    var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverloadAndNotAccessor);
                    if (flags & 524288 /* TypeAlias */ && exportedDeclarationsCount <= 2) {
                        // it is legal to merge type alias with other values
                        // so count should be either 1 (just type alias) or 2 (type alias + merged value)
                        return;
                    }
                    if (exportedDeclarationsCount > 1) {
                        for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) {
                            var declaration = declarations_8[_i];
                            if (isNotOverload(declaration)) {
                                diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id)));
                            }
                        }
                    }
                });
                links.exportsChecked = true;
            }
        }
        function isNotAccessor(declaration) {
            // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks
            return !ts.isAccessor(declaration);
        }
        function isNotOverload(declaration) {
            return (declaration.kind !== 228 /* FunctionDeclaration */ && declaration.kind !== 151 /* MethodDeclaration */) ||
                !!declaration.body;
        }
        function checkSourceElement(node) {
            if (!node) {
                return;
            }
            if (ts.isInJavaScriptFile(node) && node.jsDoc) {
                for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                    var tags = _a[_i].tags;
                    ts.forEach(tags, checkSourceElement);
                }
            }
            var kind = node.kind;
            if (cancellationToken) {
                // Only bother checking on a few construct kinds.  We don't want to be excessively
                // hitting the cancellation token on every node we check.
                switch (kind) {
                    case 233 /* ModuleDeclaration */:
                    case 229 /* ClassDeclaration */:
                    case 230 /* InterfaceDeclaration */:
                    case 228 /* FunctionDeclaration */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            switch (kind) {
                case 145 /* TypeParameter */:
                    return checkTypeParameter(node);
                case 146 /* Parameter */:
                    return checkParameter(node);
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    return checkPropertyDeclaration(node);
                case 160 /* FunctionType */:
                case 161 /* ConstructorType */:
                case 155 /* CallSignature */:
                case 156 /* ConstructSignature */:
                    return checkSignatureDeclaration(node);
                case 157 /* IndexSignature */:
                    return checkSignatureDeclaration(node);
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                    return checkMethodDeclaration(node);
                case 152 /* Constructor */:
                    return checkConstructorDeclaration(node);
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return checkAccessorDeclaration(node);
                case 159 /* TypeReference */:
                    return checkTypeReferenceNode(node);
                case 158 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 162 /* TypeQuery */:
                    return checkTypeQuery(node);
                case 163 /* TypeLiteral */:
                    return checkTypeLiteral(node);
                case 164 /* ArrayType */:
                    return checkArrayType(node);
                case 165 /* TupleType */:
                    return checkTupleType(node);
                case 166 /* UnionType */:
                case 167 /* IntersectionType */:
                    return checkUnionOrIntersectionType(node);
                case 168 /* ParenthesizedType */:
                case 170 /* TypeOperator */:
                    return checkSourceElement(node.type);
                case 277 /* JSDocAugmentsTag */:
                    return checkJSDocAugmentsTag(node);
                case 283 /* JSDocTypedefTag */:
                    return checkJSDocTypedefTag(node);
                case 279 /* JSDocParameterTag */:
                    return checkJSDocParameterTag(node);
                case 273 /* JSDocFunctionType */:
                    checkSignatureDeclaration(node);
                // falls through
                case 274 /* JSDocVariadicType */:
                case 271 /* JSDocNonNullableType */:
                case 270 /* JSDocNullableType */:
                case 268 /* JSDocAllType */:
                case 269 /* JSDocUnknownType */:
                    if (!ts.isInJavaScriptFile(node) && !ts.isInJSDoc(node)) {
                        grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
                    }
                    return;
                case 267 /* JSDocTypeExpression */:
                    return checkSourceElement(node.type);
                case 171 /* IndexedAccessType */:
                    return checkIndexedAccessType(node);
                case 172 /* MappedType */:
                    return checkMappedType(node);
                case 228 /* FunctionDeclaration */:
                    return checkFunctionDeclaration(node);
                case 207 /* Block */:
                case 234 /* ModuleBlock */:
                    return checkBlock(node);
                case 208 /* VariableStatement */:
                    return checkVariableStatement(node);
                case 210 /* ExpressionStatement */:
                    return checkExpressionStatement(node);
                case 211 /* IfStatement */:
                    return checkIfStatement(node);
                case 212 /* DoStatement */:
                    return checkDoStatement(node);
                case 213 /* WhileStatement */:
                    return checkWhileStatement(node);
                case 214 /* ForStatement */:
                    return checkForStatement(node);
                case 215 /* ForInStatement */:
                    return checkForInStatement(node);
                case 216 /* ForOfStatement */:
                    return checkForOfStatement(node);
                case 217 /* ContinueStatement */:
                case 218 /* BreakStatement */:
                    return checkBreakOrContinueStatement(node);
                case 219 /* ReturnStatement */:
                    return checkReturnStatement(node);
                case 220 /* WithStatement */:
                    return checkWithStatement(node);
                case 221 /* SwitchStatement */:
                    return checkSwitchStatement(node);
                case 222 /* LabeledStatement */:
                    return checkLabeledStatement(node);
                case 223 /* ThrowStatement */:
                    return checkThrowStatement(node);
                case 224 /* TryStatement */:
                    return checkTryStatement(node);
                case 226 /* VariableDeclaration */:
                    return checkVariableDeclaration(node);
                case 176 /* BindingElement */:
                    return checkBindingElement(node);
                case 229 /* ClassDeclaration */:
                    return checkClassDeclaration(node);
                case 230 /* InterfaceDeclaration */:
                    return checkInterfaceDeclaration(node);
                case 231 /* TypeAliasDeclaration */:
                    return checkTypeAliasDeclaration(node);
                case 232 /* EnumDeclaration */:
                    return checkEnumDeclaration(node);
                case 233 /* ModuleDeclaration */:
                    return checkModuleDeclaration(node);
                case 238 /* ImportDeclaration */:
                    return checkImportDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    return checkImportEqualsDeclaration(node);
                case 244 /* ExportDeclaration */:
                    return checkExportDeclaration(node);
                case 243 /* ExportAssignment */:
                    return checkExportAssignment(node);
                case 209 /* EmptyStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 225 /* DebuggerStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 247 /* MissingDeclaration */:
                    return checkMissingDeclaration(node);
            }
        }
        // Function and class expression bodies are checked after all statements in the enclosing body. This is
        // to ensure constructs like the following are permitted:
        //     const foo = function () {
        //        const s = foo();
        //        return "hello";
        //     }
        // Here, performing a full type check of the body of the function expression whilst in the process of
        // determining the type of foo would cause foo to be given type any because of the recursive reference.
        // Delaying the type check of the body ensures foo has been assigned a type.
        function checkNodeDeferred(node) {
            if (deferredNodes) {
                deferredNodes.push(node);
            }
        }
        function checkDeferredNodes() {
            for (var _i = 0, deferredNodes_1 = deferredNodes; _i < deferredNodes_1.length; _i++) {
                var node = deferredNodes_1[_i];
                switch (node.kind) {
                    case 186 /* FunctionExpression */:
                    case 187 /* ArrowFunction */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                        checkFunctionExpressionOrObjectLiteralMethodDeferred(node);
                        break;
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        checkAccessorDeclaration(node);
                        break;
                    case 199 /* ClassExpression */:
                        checkClassExpressionDeferred(node);
                        break;
                }
            }
        }
        function checkSourceFile(node) {
            ts.performance.mark("beforeCheck");
            checkSourceFileWorker(node);
            ts.performance.mark("afterCheck");
            ts.performance.measure("Check", "beforeCheck", "afterCheck");
        }
        // Fully type check a source file and collect the relevant diagnostics.
        function checkSourceFileWorker(node) {
            var links = getNodeLinks(node);
            if (!(links.flags & 1 /* TypeChecked */)) {
                // If skipLibCheck is enabled, skip type checking if file is a declaration file.
                // If skipDefaultLibCheck is enabled, skip type checking if file contains a
                // '/// <reference no-default-lib="true"/>' directive.
                if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) {
                    return;
                }
                // Grammar checking
                checkGrammarSourceFile(node);
                ts.clear(potentialThisCollisions);
                ts.clear(potentialNewTargetCollisions);
                deferredNodes = [];
                deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
                flowAnalysisDisabled = false;
                ts.forEach(node.statements, checkSourceElement);
                checkDeferredNodes();
                if (ts.isExternalModule(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
                if (!node.isDeclarationFile) {
                    checkUnusedIdentifiers();
                }
                deferredNodes = undefined;
                deferredUnusedIdentifierNodes = undefined;
                if (ts.isExternalOrCommonJsModule(node)) {
                    checkExternalModuleExports(node);
                }
                if (potentialThisCollisions.length) {
                    ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
                    ts.clear(potentialThisCollisions);
                }
                if (potentialNewTargetCollisions.length) {
                    ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope);
                    ts.clear(potentialNewTargetCollisions);
                }
                links.flags |= 1 /* TypeChecked */;
            }
        }
        function getDiagnostics(sourceFile, ct) {
            try {
                // Record the cancellation token so it can be checked later on during checkSourceElement.
                // Do this in a finally block so we can ensure that it gets reset back to nothing after
                // this call is done.
                cancellationToken = ct;
                return getDiagnosticsWorker(sourceFile);
            }
            finally {
                cancellationToken = undefined;
            }
        }
        function getDiagnosticsWorker(sourceFile) {
            throwIfNonDiagnosticsProducing();
            if (sourceFile) {
                // Some global diagnostics are deferred until they are needed and
                // may not be reported in the firt call to getGlobalDiagnostics.
                // We should catch these changes and report them.
                var previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                var previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;
                checkSourceFile(sourceFile);
                var semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
                var currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                if (currentGlobalDiagnostics !== previousGlobalDiagnostics) {
                    // If the arrays are not the same reference, new diagnostics were added.
                    var deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics);
                    return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics);
                }
                else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) {
                    // If the arrays are the same reference, but the length has changed, a single
                    // new diagnostic was added as DiagnosticCollection attempts to reuse the
                    // same array.
                    return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics);
                }
                return semanticDiagnostics;
            }
            // Global diagnostics are always added when a file is not provided to
            // getDiagnostics
            ts.forEach(host.getSourceFiles(), checkSourceFile);
            return diagnostics.getDiagnostics();
        }
        function getGlobalDiagnostics() {
            throwIfNonDiagnosticsProducing();
            return diagnostics.getGlobalDiagnostics();
        }
        function throwIfNonDiagnosticsProducing() {
            if (!produceDiagnostics) {
                throw new Error("Trying to get diagnostics from a type checker that does not produce them.");
            }
        }
        // Language service support
        function isInsideWithStatementBody(node) {
            if (node) {
                while (node.parent) {
                    if (node.parent.kind === 220 /* WithStatement */ && node.parent.statement === node) {
                        return true;
                    }
                    node = node.parent;
                }
            }
            return false;
        }
        function getSymbolsInScope(location, meaning) {
            if (isInsideWithStatementBody(location)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return [];
            }
            var symbols = ts.createSymbolTable();
            var isStatic = false;
            populateSymbols();
            return symbolsToArray(symbols);
            function populateSymbols() {
                while (location) {
                    if (location.locals && !isGlobalSourceFile(location)) {
                        copySymbols(location.locals, meaning);
                    }
                    switch (location.kind) {
                        case 233 /* ModuleDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 2623475 /* ModuleMember */);
                            break;
                        case 232 /* EnumDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
                            break;
                        case 199 /* ClassExpression */:
                            var className = location.name;
                            if (className) {
                                copySymbol(location.symbol, meaning);
                            }
                        // falls through
                        // this fall-through is necessary because we would like to handle
                        // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
                        case 229 /* ClassDeclaration */:
                        case 230 /* InterfaceDeclaration */:
                            // If we didn't come from static member of class or interface,
                            // add the type parameters into the symbol table
                            // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
                            // Note: that the memberFlags come from previous iteration.
                            if (!isStatic) {
                                copySymbols(getSymbolOfNode(location).members, meaning & 793064 /* Type */);
                            }
                            break;
                        case 186 /* FunctionExpression */:
                            var funcName = location.name;
                            if (funcName) {
                                copySymbol(location.symbol, meaning);
                            }
                            break;
                    }
                    if (ts.introducesArgumentsExoticObject(location)) {
                        copySymbol(argumentsSymbol, meaning);
                    }
                    isStatic = ts.hasModifier(location, 32 /* Static */);
                    location = location.parent;
                }
                copySymbols(globals, meaning);
            }
            /**
             * Copy the given symbol into symbol tables if the symbol has the given meaning
             * and it doesn't already existed in the symbol table
             * @param key a key for storing in symbol table; if undefined, use symbol.name
             * @param symbol the symbol to be added into symbol table
             * @param meaning meaning of symbol to filter by before adding to symbol table
             */
            function copySymbol(symbol, meaning) {
                if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) {
                    var id = symbol.escapedName;
                    // We will copy all symbol regardless of its reserved name because
                    // symbolsToArray will check whether the key is a reserved name and
                    // it will not copy symbol with reserved name to the array
                    if (!symbols.has(id)) {
                        symbols.set(id, symbol);
                    }
                }
            }
            function copySymbols(source, meaning) {
                if (meaning) {
                    source.forEach(function (symbol) {
                        copySymbol(symbol, meaning);
                    });
                }
            }
        }
        function isTypeDeclarationName(name) {
            return name.kind === 71 /* Identifier */ &&
                isTypeDeclaration(name.parent) &&
                name.parent.name === name;
        }
        function isTypeDeclaration(node) {
            switch (node.kind) {
                case 145 /* TypeParameter */:
                case 229 /* ClassDeclaration */:
                case 230 /* InterfaceDeclaration */:
                case 231 /* TypeAliasDeclaration */:
                case 232 /* EnumDeclaration */:
                    return true;
            }
        }
        // True if the given identifier is part of a type reference
        function isTypeReferenceIdentifier(entityName) {
            var node = entityName;
            while (node.parent && node.parent.kind === 143 /* QualifiedName */) {
                node = node.parent;
            }
            return node.parent && node.parent.kind === 159 /* TypeReference */;
        }
        function isHeritageClauseElementIdentifier(entityName) {
            var node = entityName;
            while (node.parent && node.parent.kind === 179 /* PropertyAccessExpression */) {
                node = node.parent;
            }
            return node.parent && node.parent.kind === 201 /* ExpressionWithTypeArguments */;
        }
        function forEachEnclosingClass(node, callback) {
            var result;
            while (true) {
                node = ts.getContainingClass(node);
                if (!node)
                    break;
                if (result = callback(node))
                    break;
            }
            return result;
        }
        function isNodeWithinClass(node, classDeclaration) {
            return !!forEachEnclosingClass(node, function (n) { return n === classDeclaration; });
        }
        function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) {
            while (nodeOnRightSide.parent.kind === 143 /* QualifiedName */) {
                nodeOnRightSide = nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 237 /* ImportEqualsDeclaration */) {
                return nodeOnRightSide.parent.moduleReference === nodeOnRightSide && nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 243 /* ExportAssignment */) {
                return nodeOnRightSide.parent.expression === nodeOnRightSide && nodeOnRightSide.parent;
            }
            return undefined;
        }
        function isInRightSideOfImportOrExportAssignment(node) {
            return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
        }
        function getSpecialPropertyAssignmentSymbolFromEntityName(entityName) {
            var specialPropertyAssignmentKind = ts.getSpecialPropertyAssignmentKind(entityName.parent.parent);
            switch (specialPropertyAssignmentKind) {
                case 1 /* ExportsProperty */:
                case 3 /* PrototypeProperty */:
                    return getSymbolOfNode(entityName.parent);
                case 4 /* ThisProperty */:
                case 2 /* ModuleExports */:
                case 5 /* Property */:
                    return getSymbolOfNode(entityName.parent.parent);
            }
        }
        function getSymbolOfEntityNameOrPropertyAccessExpression(entityName) {
            if (ts.isDeclarationName(entityName)) {
                return getSymbolOfNode(entityName.parent);
            }
            if (ts.isInJavaScriptFile(entityName) &&
                entityName.parent.kind === 179 /* PropertyAccessExpression */ &&
                entityName.parent === entityName.parent.parent.left) {
                // Check if this is a special property assignment
                var specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName);
                if (specialPropertyAssignmentSymbol) {
                    return specialPropertyAssignmentSymbol;
                }
            }
            if (entityName.parent.kind === 243 /* ExportAssignment */ && ts.isEntityNameExpression(entityName)) {
                return resolveEntityName(entityName, 
                /*all meanings*/ 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
            }
            if (entityName.kind !== 179 /* PropertyAccessExpression */ && isInRightSideOfImportOrExportAssignment(entityName)) {
                // Since we already checked for ExportAssignment, this really could only be an Import
                var importEqualsDeclaration = ts.getAncestor(entityName, 237 /* ImportEqualsDeclaration */);
                ts.Debug.assert(importEqualsDeclaration !== undefined);
                return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true);
            }
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            if (isHeritageClauseElementIdentifier(entityName)) {
                var meaning = 0 /* None */;
                // In an interface or class, we're definitely interested in a type.
                if (entityName.parent.kind === 201 /* ExpressionWithTypeArguments */) {
                    meaning = 793064 /* Type */;
                    // In a class 'extends' clause we are also looking for a value.
                    if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
                        meaning |= 107455 /* Value */;
                    }
                }
                else {
                    meaning = 1920 /* Namespace */;
                }
                meaning |= 2097152 /* Alias */;
                var entityNameSymbol = resolveEntityName(entityName, meaning);
                if (entityNameSymbol) {
                    return entityNameSymbol;
                }
            }
            if (entityName.parent.kind === 279 /* JSDocParameterTag */) {
                return ts.getParameterSymbolFromJSDoc(entityName.parent);
            }
            if (entityName.parent.kind === 145 /* TypeParameter */ && entityName.parent.parent.kind === 282 /* JSDocTemplateTag */) {
                ts.Debug.assert(!ts.isInJavaScriptFile(entityName)); // Otherwise `isDeclarationName` would have been true.
                var typeParameter = ts.getTypeParameterFromJsDoc(entityName.parent);
                return typeParameter && typeParameter.symbol;
            }
            if (ts.isPartOfExpression(entityName)) {
                if (ts.nodeIsMissing(entityName)) {
                    // Missing entity name.
                    return undefined;
                }
                if (entityName.kind === 71 /* Identifier */) {
                    if (ts.isJSXTagName(entityName) && isJsxIntrinsicIdentifier(entityName)) {
                        return getIntrinsicTagSymbol(entityName.parent);
                    }
                    return resolveEntityName(entityName, 107455 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
                }
                else if (entityName.kind === 179 /* PropertyAccessExpression */ || entityName.kind === 143 /* QualifiedName */) {
                    var links = getNodeLinks(entityName);
                    if (links.resolvedSymbol) {
                        return links.resolvedSymbol;
                    }
                    if (entityName.kind === 179 /* PropertyAccessExpression */) {
                        checkPropertyAccessExpression(entityName);
                    }
                    else {
                        checkQualifiedName(entityName);
                    }
                    return links.resolvedSymbol;
                }
            }
            else if (isTypeReferenceIdentifier(entityName)) {
                var meaning = entityName.parent.kind === 159 /* TypeReference */ ? 793064 /* Type */ : 1920 /* Namespace */;
                return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
            }
            else if (entityName.parent.kind === 253 /* JsxAttribute */) {
                return getJsxAttributePropertySymbol(entityName.parent);
            }
            if (entityName.parent.kind === 158 /* TypePredicate */) {
                return resolveEntityName(entityName, /*meaning*/ 1 /* FunctionScopedVariable */);
            }
            // Do we want to return undefined here?
            return undefined;
        }
        function getSymbolAtLocation(node) {
            if (node.kind === 265 /* SourceFile */) {
                return ts.isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined;
            }
            if (isInsideWithStatementBody(node)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                // This is a declaration, call getSymbolOfNode
                return getSymbolOfNode(node.parent);
            }
            else if (ts.isLiteralComputedPropertyDeclarationName(node)) {
                return getSymbolOfNode(node.parent.parent);
            }
            if (node.kind === 71 /* Identifier */) {
                if (isInRightSideOfImportOrExportAssignment(node)) {
                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
                }
                else if (node.parent.kind === 176 /* BindingElement */ &&
                    node.parent.parent.kind === 174 /* ObjectBindingPattern */ &&
                    node === node.parent.propertyName) {
                    var typeOfPattern = getTypeOfNode(node.parent.parent);
                    var propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, node.escapedText);
                    if (propertyDeclaration) {
                        return propertyDeclaration;
                    }
                }
            }
            switch (node.kind) {
                case 71 /* Identifier */:
                case 179 /* PropertyAccessExpression */:
                case 143 /* QualifiedName */:
                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
                case 99 /* ThisKeyword */:
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    if (ts.isFunctionLike(container)) {
                        var sig = getSignatureFromDeclaration(container);
                        if (sig.thisParameter) {
                            return sig.thisParameter;
                        }
                    }
                    if (ts.isInExpressionContext(node)) {
                        return checkExpression(node).symbol;
                    }
                // falls through
                case 169 /* ThisType */:
                    return getTypeFromThisTypeNode(node).symbol;
                case 97 /* SuperKeyword */:
                    return checkExpression(node).symbol;
                case 123 /* ConstructorKeyword */:
                    // constructor keyword for an overload, should take us to the definition if it exist
                    var constructorDeclaration = node.parent;
                    if (constructorDeclaration && constructorDeclaration.kind === 152 /* Constructor */) {
                        return constructorDeclaration.parent.symbol;
                    }
                    return undefined;
                case 9 /* StringLiteral */:
                    // 1). import x = require("./mo/*gotToDefinitionHere*/d")
                    // 2). External module name in an import declaration
                    // 3). Dynamic import call or require in javascript
                    if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
                        ((node.parent.kind === 238 /* ImportDeclaration */ || node.parent.kind === 244 /* ExportDeclaration */) && node.parent.moduleSpecifier === node) ||
                        ((ts.isInJavaScriptFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) || ts.isImportCall(node.parent))) {
                        return resolveExternalModuleName(node, node);
                    }
                // falls through
                case 8 /* NumericLiteral */:
                    // index access
                    var objectType = ts.isElementAccessExpression(node.parent)
                        ? node.parent.argumentExpression === node ? getTypeOfExpression(node.parent.expression) : undefined
                        : ts.isLiteralTypeNode(node.parent) && ts.isIndexedAccessTypeNode(node.parent.parent)
                            ? getTypeFromTypeNode(node.parent.parent.objectType)
                            : undefined;
                    return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores(node.text));
                case 79 /* DefaultKeyword */:
                    return getSymbolOfNode(node.parent);
                default:
                    return undefined;
            }
        }
        function getShorthandAssignmentValueSymbol(location) {
            // The function returns a value symbol of an identifier in the short-hand property assignment.
            // This is necessary as an identifier in short-hand property assignment can contains two meaning:
            // property name and property value.
            if (location && location.kind === 262 /* ShorthandPropertyAssignment */) {
                return resolveEntityName(location.name, 107455 /* Value */ | 2097152 /* Alias */);
            }
            return undefined;
        }
        /** Returns the target of an export specifier without following aliases */
        function getExportSpecifierLocalTargetSymbol(node) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node) :
                resolveEntityName(node.propertyName || node.name, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
        }
        function getTypeOfNode(node) {
            if (isInsideWithStatementBody(node)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return unknownType;
            }
            if (ts.isPartOfTypeNode(node)) {
                var typeFromTypeNode = getTypeFromTypeNode(node);
                if (typeFromTypeNode && ts.isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
                    var containingClass = ts.getContainingClass(node);
                    var classType = getTypeOfNode(containingClass);
                    typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType);
                }
                return typeFromTypeNode;
            }
            if (ts.isPartOfExpression(node)) {
                return getRegularTypeOfExpression(node);
            }
            if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
                // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
                // extends clause of a class. We handle that case here.
                var classNode = ts.getContainingClass(node);
                var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode));
                var baseType = getBaseTypes(classType)[0];
                return baseType && getTypeWithThisArgument(baseType, classType.thisType);
            }
            if (isTypeDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getDeclaredTypeOfSymbol(symbol);
            }
            if (isTypeDeclarationName(node)) {
                var symbol = getSymbolAtLocation(node);
                return symbol && getDeclaredTypeOfSymbol(symbol);
            }
            if (ts.isDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getTypeOfSymbol(symbol);
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                var symbol = getSymbolAtLocation(node);
                return symbol && getTypeOfSymbol(symbol);
            }
            if (ts.isBindingPattern(node)) {
                return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true);
            }
            if (isInRightSideOfImportOrExportAssignment(node)) {
                var symbol = getSymbolAtLocation(node);
                var declaredType = symbol && getDeclaredTypeOfSymbol(symbol);
                return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol);
            }
            return unknownType;
        }
        // Gets the type of object literal or array literal of destructuring assignment.
        // { a } from
        //     for ( { a } of elems) {
        //     }
        // [ a ] from
        //     [a] = [ some array ...]
        function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr) {
            ts.Debug.assert(expr.kind === 178 /* ObjectLiteralExpression */ || expr.kind === 177 /* ArrayLiteralExpression */);
            // If this is from "for of"
            //     for ( { a } of elems) {
            //     }
            if (expr.parent.kind === 216 /* ForOfStatement */) {
                var iteratedType = checkRightHandSideOfForOf(expr.parent.expression, expr.parent.awaitModifier);
                return checkDestructuringAssignment(expr, iteratedType || unknownType);
            }
            // If this is from "for" initializer
            //     for ({a } = elems[0];.....) { }
            if (expr.parent.kind === 194 /* BinaryExpression */) {
                var iteratedType = getTypeOfExpression(expr.parent.right);
                return checkDestructuringAssignment(expr, iteratedType || unknownType);
            }
            // If this is from nested object binding pattern
            //     for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
            if (expr.parent.kind === 261 /* PropertyAssignment */) {
                var typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent.parent);
                return checkObjectLiteralDestructuringPropertyAssignment(typeOfParentObjectLiteral || unknownType, expr.parent);
            }
            // Array literal assignment - array destructuring pattern
            ts.Debug.assert(expr.parent.kind === 177 /* ArrayLiteralExpression */);
            //    [{ property1: p1, property2 }] = elems;
            var typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent);
            var elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType;
            return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, ts.indexOf(expr.parent.elements, expr), elementType || unknownType);
        }
        // Gets the property symbol corresponding to the property in destructuring assignment
        // 'property1' from
        //     for ( { property1: a } of elems) {
        //     }
        // 'property1' at location 'a' from:
        //     [a] = [ property1, property2 ]
        function getPropertySymbolOfDestructuringAssignment(location) {
            // Get the type of the object or array literal and then look for property of given name in the type
            var typeOfObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(location.parent.parent);
            return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText);
        }
        function getRegularTypeOfExpression(expr) {
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                expr = expr.parent;
            }
            return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
        }
        /**
         * Gets either the static or instance type of a class element, based on
         * whether the element is declared as "static".
         */
        function getParentTypeOfClassElement(node) {
            var classSymbol = getSymbolOfNode(node.parent);
            return ts.hasModifier(node, 32 /* Static */)
                ? getTypeOfSymbol(classSymbol)
                : getDeclaredTypeOfSymbol(classSymbol);
        }
        // Return the list of properties of the given type, augmented with properties from Function
        // if the type has call or construct signatures
        function getAugmentedPropertiesOfType(type) {
            type = getApparentType(type);
            var propsByName = ts.createSymbolTable(getPropertiesOfType(type));
            if (getSignaturesOfType(type, 0 /* Call */).length || getSignaturesOfType(type, 1 /* Construct */).length) {
                ts.forEach(getPropertiesOfType(globalFunctionType), function (p) {
                    if (!propsByName.has(p.escapedName)) {
                        propsByName.set(p.escapedName, p);
                    }
                });
            }
            return getNamedMembers(propsByName);
        }
        function getRootSymbols(symbol) {
            if (ts.getCheckFlags(symbol) & 6 /* Synthetic */) {
                var symbols_4 = [];
                var name_3 = symbol.escapedName;
                ts.forEach(getSymbolLinks(symbol).containingType.types, function (t) {
                    var symbol = getPropertyOfType(t, name_3);
                    if (symbol) {
                        symbols_4.push(symbol);
                    }
                });
                return symbols_4;
            }
            else if (symbol.flags & 33554432 /* Transient */) {
                var transient = symbol;
                if (transient.leftSpread) {
                    return getRootSymbols(transient.leftSpread).concat(getRootSymbols(transient.rightSpread));
                }
                if (transient.syntheticOrigin) {
                    return getRootSymbols(transient.syntheticOrigin);
                }
                var target = void 0;
                var next = symbol;
                while (next = getSymbolLinks(next).target) {
                    target = next;
                }
                if (target) {
                    return [target];
                }
            }
            return [symbol];
        }
        // Emitter support
        function isArgumentsLocalBinding(node) {
            if (!ts.isGeneratedIdentifier(node)) {
                node = ts.getParseTreeNode(node, ts.isIdentifier);
                if (node) {
                    var isPropertyName_1 = node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node;
                    return !isPropertyName_1 && getReferencedValueSymbol(node) === argumentsSymbol;
                }
            }
            return false;
        }
        function moduleExportsSomeValue(moduleReferenceExpression) {
            var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
            if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                // If the module is not found or is shorthand, assume that it may export a value.
                return true;
            }
            var hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol);
            // if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment
            // otherwise it will return moduleSymbol itself
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            var symbolLinks = getSymbolLinks(moduleSymbol);
            if (symbolLinks.exportsSomeValue === undefined) {
                // for export assignments - check if resolved symbol for RHS is itself a value
                // otherwise - check if at least one export is value
                symbolLinks.exportsSomeValue = hasExportAssignment
                    ? !!(moduleSymbol.flags & 107455 /* Value */)
                    : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue);
            }
            return symbolLinks.exportsSomeValue;
            function isValue(s) {
                s = resolveSymbol(s);
                return s && !!(s.flags & 107455 /* Value */);
            }
        }
        function isNameOfModuleOrEnumDeclaration(node) {
            var parent = node.parent;
            return parent && ts.isModuleOrEnumDeclaration(parent) && node === parent.name;
        }
        // When resolved as an expression identifier, if the given node references an exported entity, return the declaration
        // node of the exported entity's container. Otherwise, return undefined.
        function getReferencedExportContainer(node, prefixLocals) {
            node = ts.getParseTreeNode(node, ts.isIdentifier);
            if (node) {
                // When resolving the export container for the name of a module or enum
                // declaration, we need to start resolution at the declaration's container.
                // Otherwise, we could incorrectly resolve the export container as the
                // declaration if it contains an exported member with the same name.
                var symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node));
                if (symbol) {
                    if (symbol.flags & 1048576 /* ExportValue */) {
                        // If we reference an exported entity within the same module declaration, then whether
                        // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
                        // kinds that we do NOT prefix.
                        var exportSymbol = getMergedSymbol(symbol.exportSymbol);
                        if (!prefixLocals && exportSymbol.flags & 944 /* ExportHasLocal */) {
                            return undefined;
                        }
                        symbol = exportSymbol;
                    }
                    var parentSymbol_1 = getParentOfSymbol(symbol);
                    if (parentSymbol_1) {
                        if (parentSymbol_1.flags & 512 /* ValueModule */ && parentSymbol_1.valueDeclaration.kind === 265 /* SourceFile */) {
                            var symbolFile = parentSymbol_1.valueDeclaration;
                            var referenceFile = ts.getSourceFileOfNode(node);
                            // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
                            var symbolIsUmdExport = symbolFile !== referenceFile;
                            return symbolIsUmdExport ? undefined : symbolFile;
                        }
                        return ts.findAncestor(node.parent, function (n) { return ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol_1; });
                    }
                }
            }
        }
        // When resolved as an expression identifier, if the given node references an import, return the declaration of
        // that import. Otherwise, return undefined.
        function getReferencedImportDeclaration(node) {
            node = ts.getParseTreeNode(node, ts.isIdentifier);
            if (node) {
                var symbol = getReferencedValueSymbol(node);
                // We should only get the declaration of an alias if there isn't a local value
                // declaration for the symbol
                if (isNonLocalAlias(symbol, /*excludes*/ 107455 /* Value */)) {
                    return getDeclarationOfAliasSymbol(symbol);
                }
            }
            return undefined;
        }
        function isSymbolOfDeclarationWithCollidingName(symbol) {
            if (symbol.flags & 418 /* BlockScoped */) {
                var links = getSymbolLinks(symbol);
                if (links.isDeclarationWithCollidingName === undefined) {
                    var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
                    if (ts.isStatementWithLocals(container)) {
                        var nodeLinks_1 = getNodeLinks(symbol.valueDeclaration);
                        if (resolveName(container.parent, symbol.escapedName, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) {
                            // redeclaration - always should be renamed
                            links.isDeclarationWithCollidingName = true;
                        }
                        else if (nodeLinks_1.flags & 131072 /* CapturedBlockScopedBinding */) {
                            // binding is captured in the function
                            // should be renamed if:
                            // - binding is not top level - top level bindings never collide with anything
                            // AND
                            //   - binding is not declared in loop, should be renamed to avoid name reuse across siblings
                            //     let a, b
                            //     { let x = 1; a = () => x;  }
                            //     { let x = 100; b = () => x; }
                            //     console.log(a()); // should print '1'
                            //     console.log(b()); // should print '100'
                            //     OR
                            //   - binding is declared inside loop but not in inside initializer of iteration statement or directly inside loop body
                            //     * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly
                            //     * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus
                            //       they will not collide with anything
                            var isDeclaredInLoop = nodeLinks_1.flags & 262144 /* BlockScopedBindingInLoop */;
                            var inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false);
                            var inLoopBodyBlock = container.kind === 207 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false);
                            links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock));
                        }
                        else {
                            links.isDeclarationWithCollidingName = false;
                        }
                    }
                }
                return links.isDeclarationWithCollidingName;
            }
            return false;
        }
        // When resolved as an expression identifier, if the given node references a nested block scoped entity with
        // a name that either hides an existing name or might hide it when compiled downlevel,
        // return the declaration of that entity. Otherwise, return undefined.
        function getReferencedDeclarationWithCollidingName(node) {
            if (!ts.isGeneratedIdentifier(node)) {
                node = ts.getParseTreeNode(node, ts.isIdentifier);
                if (node) {
                    var symbol = getReferencedValueSymbol(node);
                    if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) {
                        return symbol.valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an
        // existing name or might hide a name when compiled downlevel
        function isDeclarationWithCollidingName(node) {
            node = ts.getParseTreeNode(node, ts.isDeclaration);
            if (node) {
                var symbol = getSymbolOfNode(node);
                if (symbol) {
                    return isSymbolOfDeclarationWithCollidingName(symbol);
                }
            }
            return false;
        }
        function isValueAliasDeclaration(node) {
            switch (node.kind) {
                case 237 /* ImportEqualsDeclaration */:
                case 239 /* ImportClause */:
                case 240 /* NamespaceImport */:
                case 242 /* ImportSpecifier */:
                case 246 /* ExportSpecifier */:
                    return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
                case 244 /* ExportDeclaration */:
                    var exportClause = node.exportClause;
                    return exportClause && ts.forEach(exportClause.elements, isValueAliasDeclaration);
                case 243 /* ExportAssignment */:
                    return node.expression
                        && node.expression.kind === 71 /* Identifier */
                        ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol)
                        : true;
            }
            return false;
        }
        function isTopLevelValueImportEqualsWithEntityName(node) {
            node = ts.getParseTreeNode(node, ts.isImportEqualsDeclaration);
            if (node === undefined || node.parent.kind !== 265 /* SourceFile */ || !ts.isInternalModuleImportEqualsDeclaration(node)) {
                // parent is not source file or it is not reference to internal module
                return false;
            }
            var isValue = isAliasResolvedToValue(getSymbolOfNode(node));
            return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference);
        }
        function isAliasResolvedToValue(symbol) {
            var target = resolveAlias(symbol);
            if (target === unknownSymbol) {
                return true;
            }
            // const enums and modules that contain only const enums are not considered values from the emit perspective
            // unless 'preserveConstEnums' option is set to true
            return target.flags & 107455 /* Value */ &&
                (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target));
        }
        function isConstEnumOrConstEnumOnlyModule(s) {
            return isConstEnumSymbol(s) || s.constEnumOnlyModule;
        }
        function isReferencedAliasDeclaration(node, checkChildren) {
            if (ts.isAliasSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                if (symbol && getSymbolLinks(symbol).referenced) {
                    return true;
                }
            }
            if (checkChildren) {
                return ts.forEachChild(node, function (node) { return isReferencedAliasDeclaration(node, checkChildren); });
            }
            return false;
        }
        function isImplementationOfOverload(node) {
            if (ts.nodeIsPresent(node.body)) {
                var symbol = getSymbolOfNode(node);
                var signaturesOfSymbol = getSignaturesOfSymbol(symbol);
                // If this function body corresponds to function with multiple signature, it is implementation of overload
                // e.g.: function foo(a: string): string;
                //       function foo(a: number): number;
                //       function foo(a: any) { // This is implementation of the overloads
                //           return a;
                //       }
                return signaturesOfSymbol.length > 1 ||
                    // If there is single signature for the symbol, it is overload if that signature isn't coming from the node
                    // e.g.: function foo(a: string): string;
                    //       function foo(a: any) { // This is implementation of the overloads
                    //           return a;
                    //       }
                    (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node);
            }
            return false;
        }
        function isRequiredInitializedParameter(parameter) {
            return strictNullChecks &&
                !isOptionalParameter(parameter) &&
                parameter.initializer &&
                !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isOptionalUninitializedParameterProperty(parameter) {
            return strictNullChecks &&
                isOptionalParameter(parameter) &&
                !parameter.initializer &&
                ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function getNodeCheckFlags(node) {
            return getNodeLinks(node).flags;
        }
        function getEnumMemberValue(node) {
            computeEnumMemberValues(node.parent);
            return getNodeLinks(node).enumMemberValue;
        }
        function canHaveConstantValue(node) {
            switch (node.kind) {
                case 264 /* EnumMember */:
                case 179 /* PropertyAccessExpression */:
                case 180 /* ElementAccessExpression */:
                    return true;
            }
            return false;
        }
        function getConstantValue(node) {
            if (node.kind === 264 /* EnumMember */) {
                return getEnumMemberValue(node);
            }
            var symbol = getNodeLinks(node).resolvedSymbol;
            if (symbol && (symbol.flags & 8 /* EnumMember */)) {
                // inline property\index accesses only for const enums
                if (ts.isConstEnumDeclaration(symbol.valueDeclaration.parent)) {
                    return getEnumMemberValue(symbol.valueDeclaration);
                }
            }
            return undefined;
        }
        function isFunctionType(type) {
            return type.flags & 32768 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0;
        }
        function getTypeReferenceSerializationKind(typeName, location) {
            // ensure both `typeName` and `location` are parse tree nodes.
            typeName = ts.getParseTreeNode(typeName, ts.isEntityName);
            if (!typeName)
                return ts.TypeReferenceSerializationKind.Unknown;
            if (location) {
                location = ts.getParseTreeNode(location);
                if (!location)
                    return ts.TypeReferenceSerializationKind.Unknown;
            }
            // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
            var valueSymbol = resolveEntityName(typeName, 107455 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
            var typeSymbol = resolveEntityName(typeName, 793064 /* Type */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            if (valueSymbol && valueSymbol === typeSymbol) {
                var globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
                if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
                    return ts.TypeReferenceSerializationKind.Promise;
                }
                var constructorType = getTypeOfSymbol(valueSymbol);
                if (constructorType && isConstructorType(constructorType)) {
                    return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
                }
            }
            // We might not be able to resolve type symbol so use unknown type in that case (eg error case)
            if (!typeSymbol) {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
            var type = getDeclaredTypeOfSymbol(typeSymbol);
            if (type === unknownType) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            else if (type.flags & 1 /* Any */) {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
            else if (isTypeAssignableToKind(type, 1024 /* Void */ | 6144 /* Nullable */ | 8192 /* Never */)) {
                return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType;
            }
            else if (isTypeAssignableToKind(type, 136 /* BooleanLike */)) {
                return ts.TypeReferenceSerializationKind.BooleanType;
            }
            else if (isTypeAssignableToKind(type, 84 /* NumberLike */)) {
                return ts.TypeReferenceSerializationKind.NumberLikeType;
            }
            else if (isTypeAssignableToKind(type, 262178 /* StringLike */)) {
                return ts.TypeReferenceSerializationKind.StringLikeType;
            }
            else if (isTupleType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else if (isTypeAssignableToKind(type, 512 /* ESSymbol */)) {
                return ts.TypeReferenceSerializationKind.ESSymbolType;
            }
            else if (isFunctionType(type)) {
                return ts.TypeReferenceSerializationKind.TypeWithCallSignature;
            }
            else if (isArrayType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
        }
        function writeTypeOfDeclaration(declaration, enclosingDeclaration, flags, writer) {
            // Get type of the symbol if this is the valid symbol otherwise get type at location
            var symbol = getSymbolOfNode(declaration);
            var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* Signature */))
                ? getWidenedLiteralType(getTypeOfSymbol(symbol))
                : unknownType;
            if (flags & 8192 /* AddUndefined */) {
                type = getNullableType(type, 2048 /* Undefined */);
            }
            getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
        }
        function writeReturnTypeOfSignatureDeclaration(signatureDeclaration, enclosingDeclaration, flags, writer) {
            var signature = getSignatureFromDeclaration(signatureDeclaration);
            getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags);
        }
        function writeTypeOfExpression(expr, enclosingDeclaration, flags, writer) {
            var type = getWidenedType(getRegularTypeOfExpression(expr));
            getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
        }
        function hasGlobalName(name) {
            return globals.has(ts.escapeLeadingUnderscores(name));
        }
        function getReferencedValueSymbol(reference, startInDeclarationContainer) {
            var resolvedSymbol = getNodeLinks(reference).resolvedSymbol;
            if (resolvedSymbol) {
                return resolvedSymbol;
            }
            var location = reference;
            if (startInDeclarationContainer) {
                // When resolving the name of a declaration as a value, we need to start resolution
                // at a point outside of the declaration.
                var parent = reference.parent;
                if (ts.isDeclaration(parent) && reference === parent.name) {
                    location = getDeclarationContainer(parent);
                }
            }
            return resolveName(location, reference.escapedText, 107455 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
        }
        function getReferencedValueDeclaration(reference) {
            if (!ts.isGeneratedIdentifier(reference)) {
                reference = ts.getParseTreeNode(reference, ts.isIdentifier);
                if (reference) {
                    var symbol = getReferencedValueSymbol(reference);
                    if (symbol) {
                        return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        function isLiteralConstDeclaration(node) {
            if (ts.isConst(node)) {
                var type = getTypeOfSymbol(getSymbolOfNode(node));
                return !!(type.flags & 96 /* StringOrNumberLiteral */ && type.flags & 1048576 /* FreshLiteral */);
            }
            return false;
        }
        function writeLiteralConstValue(node, writer) {
            var type = getTypeOfSymbol(getSymbolOfNode(node));
            writer.writeStringLiteral(literalTypeToString(type));
        }
        function createResolver() {
            // this variable and functions that use it are deliberately moved here from the outer scope
            // to avoid scope pollution
            var resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives();
            var fileToDirective;
            if (resolvedTypeReferenceDirectives) {
                // populate reverse mapping: file path -> type reference directive that was resolved to this file
                fileToDirective = ts.createMap();
                resolvedTypeReferenceDirectives.forEach(function (resolvedDirective, key) {
                    if (!resolvedDirective) {
                        return;
                    }
                    var file = host.getSourceFile(resolvedDirective.resolvedFileName);
                    fileToDirective.set(file.path, key);
                });
            }
            return {
                getReferencedExportContainer: getReferencedExportContainer,
                getReferencedImportDeclaration: getReferencedImportDeclaration,
                getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName,
                isDeclarationWithCollidingName: isDeclarationWithCollidingName,
                isValueAliasDeclaration: function (node) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated like values.
                    return node ? isValueAliasDeclaration(node) : true;
                },
                hasGlobalName: hasGlobalName,
                isReferencedAliasDeclaration: function (node, checkChildren) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated as referenced.
                    return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
                },
                getNodeCheckFlags: function (node) {
                    node = ts.getParseTreeNode(node);
                    return node ? getNodeCheckFlags(node) : undefined;
                },
                isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName,
                isDeclarationVisible: isDeclarationVisible,
                isImplementationOfOverload: isImplementationOfOverload,
                isRequiredInitializedParameter: isRequiredInitializedParameter,
                isOptionalUninitializedParameterProperty: isOptionalUninitializedParameterProperty,
                writeTypeOfDeclaration: writeTypeOfDeclaration,
                writeReturnTypeOfSignatureDeclaration: writeReturnTypeOfSignatureDeclaration,
                writeTypeOfExpression: writeTypeOfExpression,
                isSymbolAccessible: isSymbolAccessible,
                isEntityNameVisible: isEntityNameVisible,
                getConstantValue: function (node) {
                    node = ts.getParseTreeNode(node, canHaveConstantValue);
                    return node ? getConstantValue(node) : undefined;
                },
                collectLinkedAliases: collectLinkedAliases,
                getReferencedValueDeclaration: getReferencedValueDeclaration,
                getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
                isOptionalParameter: isOptionalParameter,
                moduleExportsSomeValue: moduleExportsSomeValue,
                isArgumentsLocalBinding: isArgumentsLocalBinding,
                getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration,
                getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName,
                getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol,
                isLiteralConstDeclaration: isLiteralConstDeclaration,
                writeLiteralConstValue: writeLiteralConstValue,
                getJsxFactoryEntity: function () { return _jsxFactoryEntity; }
            };
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForEntityName(node) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                // property access can only be used as values
                // qualified names can only be used as types\namespaces
                // identifiers are treated as values only if they appear in type queries
                var meaning = (node.kind === 179 /* PropertyAccessExpression */) || (node.kind === 71 /* Identifier */ && isInTypeQuery(node))
                    ? 107455 /* Value */ | 1048576 /* ExportValue */
                    : 793064 /* Type */ | 1920 /* Namespace */;
                var symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
                return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForSymbol(symbol, meaning) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                if (!isSymbolFromTypeDeclarationFile(symbol)) {
                    return undefined;
                }
                // check what declarations in the symbol can contribute to the target meaning
                var typeReferenceDirectives;
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    // check meaning of the local symbol to see if declaration needs to be analyzed further
                    if (decl.symbol && decl.symbol.flags & meaning) {
                        var file = ts.getSourceFileOfNode(decl);
                        var typeReferenceDirective = fileToDirective.get(file.path);
                        if (typeReferenceDirective) {
                            (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
                        }
                        else {
                            // found at least one entry that does not originate from type reference directive
                            return undefined;
                        }
                    }
                }
                return typeReferenceDirectives;
            }
            function isSymbolFromTypeDeclarationFile(symbol) {
                // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern)
                if (!symbol.declarations) {
                    return false;
                }
                // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope
                // external modules cannot define or contribute to type declaration files
                var current = symbol;
                while (true) {
                    var parent = getParentOfSymbol(current);
                    if (parent) {
                        current = parent;
                    }
                    else {
                        break;
                    }
                }
                if (current.valueDeclaration && current.valueDeclaration.kind === 265 /* SourceFile */ && current.flags & 512 /* ValueModule */) {
                    return false;
                }
                // check that at least one declaration of top level symbol originates from type declaration file
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var file = ts.getSourceFileOfNode(decl);
                    if (fileToDirective.has(file.path)) {
                        return true;
                    }
                }
                return false;
            }
        }
        function getExternalModuleFileFromDeclaration(declaration) {
            var specifier = ts.getExternalModuleName(declaration);
            var moduleSymbol = resolveExternalModuleNameWorker(specifier, specifier, /*moduleNotFoundError*/ undefined);
            if (!moduleSymbol) {
                return undefined;
            }
            return ts.getDeclarationOfKind(moduleSymbol, 265 /* SourceFile */);
        }
        function initializeTypeChecker() {
            // Bind all source files and propagate errors
            for (var _i = 0, _a = host.getSourceFiles(); _i < _a.length; _i++) {
                var file = _a[_i];
                ts.bindSourceFile(file, compilerOptions);
            }
            // Initialize global symbol table
            var augmentations;
            for (var _b = 0, _c = host.getSourceFiles(); _b < _c.length; _b++) {
                var file = _c[_b];
                if (!ts.isExternalOrCommonJsModule(file)) {
                    mergeSymbolTable(globals, file.locals);
                }
                if (file.patternAmbientModules && file.patternAmbientModules.length) {
                    patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules);
                }
                if (file.moduleAugmentations.length) {
                    (augmentations || (augmentations = [])).push(file.moduleAugmentations);
                }
                if (file.symbol && file.symbol.globalExports) {
                    // Merge in UMD exports with first-in-wins semantics (see #9771)
                    var source = file.symbol.globalExports;
                    source.forEach(function (sourceSymbol, id) {
                        if (!globals.has(id)) {
                            globals.set(id, sourceSymbol);
                        }
                    });
                }
            }
            if (augmentations) {
                // merge module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _d = 0, augmentations_1 = augmentations; _d < augmentations_1.length; _d++) {
                    var list = augmentations_1[_d];
                    for (var _e = 0, list_1 = list; _e < list_1.length; _e++) {
                        var augmentation = list_1[_e];
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            // Setup global builtins
            addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
            getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
            getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments", /*arity*/ 0, /*reportErrors*/ true);
            getSymbolLinks(unknownSymbol).type = unknownType;
            // Initialize special types
            globalArrayType = getGlobalType("Array", /*arity*/ 1, /*reportErrors*/ true);
            globalObjectType = getGlobalType("Object", /*arity*/ 0, /*reportErrors*/ true);
            globalFunctionType = getGlobalType("Function", /*arity*/ 0, /*reportErrors*/ true);
            globalStringType = getGlobalType("String", /*arity*/ 0, /*reportErrors*/ true);
            globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true);
            globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true);
            globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true);
            anyArrayType = createArrayType(anyType);
            autoArrayType = createArrayType(autoType);
            globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1);
            anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
            globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
        }
        function checkExternalEmitHelpers(location, helpers) {
            if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
                var sourceFile = ts.getSourceFileOfNode(location);
                if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !ts.isInAmbientContext(location)) {
                    var helpersModule = resolveHelpersModule(sourceFile, location);
                    if (helpersModule !== unknownSymbol) {
                        var uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
                        for (var helper = 1 /* FirstEmitHelper */; helper <= 65536 /* LastEmitHelper */; helper <<= 1) {
                            if (uncheckedHelpers & helper) {
                                var name = getHelperName(helper);
                                var symbol = getSymbol(helpersModule.exports, ts.escapeLeadingUnderscores(name), 107455 /* Value */);
                                if (!symbol) {
                                    error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, ts.externalHelpersModuleNameText, name);
                                }
                            }
                        }
                    }
                    requestedExternalEmitHelpers |= helpers;
                }
            }
        }
        function getHelperName(helper) {
            switch (helper) {
                case 1 /* Extends */: return "__extends";
                case 2 /* Assign */: return "__assign";
                case 4 /* Rest */: return "__rest";
                case 8 /* Decorate */: return "__decorate";
                case 16 /* Metadata */: return "__metadata";
                case 32 /* Param */: return "__param";
                case 64 /* Awaiter */: return "__awaiter";
                case 128 /* Generator */: return "__generator";
                case 256 /* Values */: return "__values";
                case 512 /* Read */: return "__read";
                case 1024 /* Spread */: return "__spread";
                case 2048 /* Await */: return "__await";
                case 4096 /* AsyncGenerator */: return "__asyncGenerator";
                case 8192 /* AsyncDelegator */: return "__asyncDelegator";
                case 16384 /* AsyncValues */: return "__asyncValues";
                case 32768 /* ExportStar */: return "__exportStar";
                case 65536 /* MakeTemplateObject */: return "__makeTemplateObject";
                default: ts.Debug.fail("Unrecognized helper");
            }
        }
        function resolveHelpersModule(node, errorNode) {
            if (!externalHelpersModule) {
                externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
            }
            return externalHelpersModule;
        }
        // GRAMMAR CHECKING
        function checkGrammarDecorators(node) {
            if (!node.decorators) {
                return false;
            }
            if (!ts.nodeCanBeDecorated(node)) {
                if (node.kind === 151 /* MethodDeclaration */ && !ts.nodeIsPresent(node.body)) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
                }
                else {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_are_not_valid_here);
                }
            }
            else if (node.kind === 153 /* GetAccessor */ || node.kind === 154 /* SetAccessor */) {
                var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
                if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
                }
            }
            return false;
        }
        function checkGrammarModifiers(node) {
            var quickResult = reportObviousModifierErrors(node);
            if (quickResult !== undefined) {
                return quickResult;
            }
            var lastStatic, lastDeclare, lastAsync, lastReadonly;
            var flags = 0 /* None */;
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                if (modifier.kind !== 131 /* ReadonlyKeyword */) {
                    if (node.kind === 148 /* PropertySignature */ || node.kind === 150 /* MethodSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind));
                    }
                    if (node.kind === 157 /* IndexSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind));
                    }
                }
                switch (modifier.kind) {
                    case 76 /* ConstKeyword */:
                        if (node.kind !== 232 /* EnumDeclaration */ && node.parent.kind === 229 /* ClassDeclaration */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(76 /* ConstKeyword */));
                        }
                        break;
                    case 114 /* PublicKeyword */:
                    case 113 /* ProtectedKeyword */:
                    case 112 /* PrivateKeyword */:
                        var text = visibilityToString(ts.modifierToFlag(modifier.kind));
                        if (flags & 28 /* AccessibilityModifier */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen);
                        }
                        else if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
                        }
                        else if (node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
                        }
                        else if (flags & 128 /* Abstract */) {
                            if (modifier.kind === 112 /* PrivateKeyword */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
                            }
                            else {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
                            }
                        }
                        flags |= ts.modifierToFlag(modifier.kind);
                        break;
                    case 115 /* StaticKeyword */:
                        if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
                        }
                        else if (node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
                        }
                        else if (node.kind === 146 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                        }
                        flags |= 32 /* Static */;
                        lastStatic = modifier;
                        break;
                    case 131 /* ReadonlyKeyword */:
                        if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly");
                        }
                        else if (node.kind !== 149 /* PropertyDeclaration */ && node.kind !== 148 /* PropertySignature */ && node.kind !== 157 /* IndexSignature */ && node.kind !== 146 /* Parameter */) {
                            // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property.
                            return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
                        }
                        flags |= 64 /* Readonly */;
                        lastReadonly = modifier;
                        break;
                    case 84 /* ExportKeyword */:
                        if (flags & 1 /* Export */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export");
                        }
                        else if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
                        }
                        else if (node.parent.kind === 229 /* ClassDeclaration */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
                        }
                        else if (node.kind === 146 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
                        }
                        flags |= 1 /* Export */;
                        break;
                    case 79 /* DefaultKeyword */:
                        var container = node.parent.kind === 265 /* SourceFile */ ? node.parent : node.parent.parent;
                        if (container.kind === 233 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                        }
                        flags |= 512 /* Default */;
                        break;
                    case 124 /* DeclareKeyword */:
                        if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (node.parent.kind === 229 /* ClassDeclaration */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
                        }
                        else if (node.kind === 146 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
                        }
                        else if (ts.isInAmbientContext(node.parent) && node.parent.kind === 234 /* ModuleBlock */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
                        }
                        flags |= 2 /* Ambient */;
                        lastDeclare = modifier;
                        break;
                    case 117 /* AbstractKeyword */:
                        if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract");
                        }
                        if (node.kind !== 229 /* ClassDeclaration */) {
                            if (node.kind !== 151 /* MethodDeclaration */ &&
                                node.kind !== 149 /* PropertyDeclaration */ &&
                                node.kind !== 153 /* GetAccessor */ &&
                                node.kind !== 154 /* SetAccessor */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
                            }
                            if (!(node.parent.kind === 229 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
                            }
                            if (flags & 32 /* Static */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                            }
                            if (flags & 8 /* Private */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
                            }
                        }
                        flags |= 128 /* Abstract */;
                        break;
                    case 120 /* AsyncKeyword */:
                        if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async");
                        }
                        else if (flags & 2 /* Ambient */ || ts.isInAmbientContext(node.parent)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (node.kind === 146 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
                        }
                        flags |= 256 /* Async */;
                        lastAsync = modifier;
                        break;
                }
            }
            if (node.kind === 152 /* Constructor */) {
                if (flags & 32 /* Static */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
                }
                if (flags & 128 /* Abstract */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract");
                }
                else if (flags & 256 /* Async */) {
                    return grammarErrorOnNode(lastAsync, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
                }
                else if (flags & 64 /* Readonly */) {
                    return grammarErrorOnNode(lastReadonly, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly");
                }
                return;
            }
            else if ((node.kind === 238 /* ImportDeclaration */ || node.kind === 237 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) {
                return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
            }
            else if (node.kind === 146 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && ts.isBindingPattern(node.name)) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern);
            }
            else if (node.kind === 146 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && node.dotDotDotToken) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter);
            }
            if (flags & 256 /* Async */) {
                return checkGrammarAsyncModifier(node, lastAsync);
            }
        }
        /**
         * true | false: Early return this value from checkGrammarModifiers.
         * undefined: Need to do full checking on the modifiers.
         */
        function reportObviousModifierErrors(node) {
            return !node.modifiers
                ? false
                : shouldReportBadModifier(node)
                    ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here)
                    : undefined;
        }
        function shouldReportBadModifier(node) {
            switch (node.kind) {
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 152 /* Constructor */:
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 157 /* IndexSignature */:
                case 233 /* ModuleDeclaration */:
                case 238 /* ImportDeclaration */:
                case 237 /* ImportEqualsDeclaration */:
                case 244 /* ExportDeclaration */:
                case 243 /* ExportAssignment */:
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                case 146 /* Parameter */:
                    return false;
                default:
                    if (node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
                        return false;
                    }
                    switch (node.kind) {
                        case 228 /* FunctionDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 120 /* AsyncKeyword */);
                        case 229 /* ClassDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 117 /* AbstractKeyword */);
                        case 230 /* InterfaceDeclaration */:
                        case 208 /* VariableStatement */:
                        case 231 /* TypeAliasDeclaration */:
                            return true;
                        case 232 /* EnumDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 76 /* ConstKeyword */);
                        default:
                            ts.Debug.fail();
                            return false;
                    }
            }
        }
        function nodeHasAnyModifiersExcept(node, allowedModifier) {
            return node.modifiers.length > 1 || node.modifiers[0].kind !== allowedModifier;
        }
        function checkGrammarAsyncModifier(node, asyncModifier) {
            switch (node.kind) {
                case 151 /* MethodDeclaration */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    return false;
            }
            return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async");
        }
        function checkGrammarForDisallowedTrailingComma(list) {
            if (list && list.hasTrailingComma) {
                var start = list.end - ",".length;
                var end = list.end;
                return grammarErrorAtPos(list[0], start, end - start, ts.Diagnostics.Trailing_comma_not_allowed);
            }
        }
        function checkGrammarTypeParameterList(typeParameters, file) {
            if (checkGrammarForDisallowedTrailingComma(typeParameters)) {
                return true;
            }
            if (typeParameters && typeParameters.length === 0) {
                var start = typeParameters.pos - "<".length;
                var end = ts.skipTrivia(file.text, typeParameters.end) + ">".length;
                return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty);
            }
        }
        function checkGrammarParameterList(parameters) {
            var seenOptionalParameter = false;
            var parameterCount = parameters.length;
            for (var i = 0; i < parameterCount; i++) {
                var parameter = parameters[i];
                if (parameter.dotDotDotToken) {
                    if (i !== (parameterCount - 1)) {
                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                    }
                    if (ts.isBindingPattern(parameter.name)) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
                    }
                    if (parameter.questionToken) {
                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional);
                    }
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer);
                    }
                }
                else if (parameter.questionToken) {
                    seenOptionalParameter = true;
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
                    }
                }
                else if (seenOptionalParameter && !parameter.initializer) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
                }
            }
        }
        function checkGrammarFunctionLikeDeclaration(node) {
            // Prevent cascading error by short-circuit
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
                checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
        }
        function checkGrammarClassLikeDeclaration(node) {
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file);
        }
        function checkGrammarArrowFunction(node, file) {
            if (node.kind === 187 /* ArrowFunction */) {
                var arrowFunction = node;
                var startLine = ts.getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.pos).line;
                var endLine = ts.getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.end).line;
                if (startLine !== endLine) {
                    return grammarErrorOnNode(arrowFunction.equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow);
                }
            }
            return false;
        }
        function checkGrammarIndexSignatureParameters(node) {
            var parameter = node.parameters[0];
            if (node.parameters.length !== 1) {
                if (parameter) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
                else {
                    return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
            }
            if (parameter.dotDotDotToken) {
                return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
            }
            if (ts.hasModifiers(parameter)) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
            }
            if (parameter.questionToken) {
                return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
            }
            if (parameter.initializer) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
            }
            if (!parameter.type) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
            }
            if (parameter.type.kind !== 136 /* StringKeyword */ && parameter.type.kind !== 133 /* NumberKeyword */) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_string_or_number);
            }
            if (!node.type) {
                return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation);
            }
        }
        function checkGrammarIndexSignature(node) {
            // Prevent cascading error by short-circuit
            return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node);
        }
        function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) {
            if (typeArguments && typeArguments.length === 0) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var start = typeArguments.pos - "<".length;
                var end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length;
                return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
            }
        }
        function checkGrammarTypeArguments(node, typeArguments) {
            return checkGrammarForDisallowedTrailingComma(typeArguments) ||
                checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
        }
        function checkGrammarForOmittedArgument(args) {
            if (args) {
                for (var _i = 0, args_5 = args; _i < args_5.length; _i++) {
                    var arg = args_5[_i];
                    if (arg.kind === 200 /* OmittedExpression */) {
                        return grammarErrorAtPos(arg, arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
                    }
                }
            }
        }
        function checkGrammarArguments(args) {
            return checkGrammarForOmittedArgument(args);
        }
        function checkGrammarHeritageClause(node) {
            var types = node.types;
            if (checkGrammarForDisallowedTrailingComma(types)) {
                return true;
            }
            if (types && types.length === 0) {
                var listType = ts.tokenToString(node.token);
                return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
            }
            return ts.forEach(types, checkGrammarExpressionWithTypeArguments);
        }
        function checkGrammarExpressionWithTypeArguments(node) {
            return checkGrammarTypeArguments(node, node.typeArguments);
        }
        function checkGrammarClassDeclarationHeritageClauses(node) {
            var seenExtendsClause = false;
            var seenImplementsClause = false;
            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 85 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause);
                        }
                        if (heritageClause.types.length > 1) {
                            return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 108 /* ImplementsKeyword */);
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen);
                        }
                        seenImplementsClause = true;
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
        }
        function checkGrammarInterfaceDeclaration(node) {
            var seenExtendsClause = false;
            if (node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 85 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 108 /* ImplementsKeyword */);
                        return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause);
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
            return false;
        }
        function checkGrammarComputedPropertyName(node) {
            // If node is not a computedPropertyName, just skip the grammar checking
            if (node.kind !== 144 /* ComputedPropertyName */) {
                return false;
            }
            var computedPropertyName = node;
            if (computedPropertyName.expression.kind === 194 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 26 /* CommaToken */) {
                return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
            }
        }
        function checkGrammarForGenerator(node) {
            if (node.asteriskToken) {
                ts.Debug.assert(node.kind === 228 /* FunctionDeclaration */ ||
                    node.kind === 186 /* FunctionExpression */ ||
                    node.kind === 151 /* MethodDeclaration */);
                if (ts.isInAmbientContext(node)) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
                }
                if (!node.body) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
                }
            }
        }
        function checkGrammarForInvalidQuestionMark(questionToken, message) {
            if (questionToken) {
                return grammarErrorOnNode(questionToken, message);
            }
        }
        function checkGrammarObjectLiteralExpression(node, inDestructuring) {
            var seen = ts.createUnderscoreEscapedMap();
            var Property = 1;
            var GetAccessor = 2;
            var SetAccessor = 4;
            var GetOrSetAccessor = GetAccessor | SetAccessor;
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var prop = _a[_i];
                if (prop.kind === 263 /* SpreadAssignment */) {
                    continue;
                }
                var name = prop.name;
                if (name.kind === 144 /* ComputedPropertyName */) {
                    // If the name is not a ComputedPropertyName, the grammar checking will skip it
                    checkGrammarComputedPropertyName(name);
                }
                if (prop.kind === 262 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
                    // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
                    // outside of destructuring it is a syntax error
                    return grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
                }
                // Modifiers are never allowed on properties except for 'async' on a method declaration
                if (prop.modifiers) {
                    for (var _b = 0, _c = prop.modifiers; _b < _c.length; _b++) {
                        var mod = _c[_b];
                        if (mod.kind !== 120 /* AsyncKeyword */ || prop.kind !== 151 /* MethodDeclaration */) {
                            grammarErrorOnNode(mod, ts.Diagnostics._0_modifier_cannot_be_used_here, ts.getTextOfNode(mod));
                        }
                    }
                }
                // ECMA-262 11.1.5 Object Initializer
                // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                // IsDataDescriptor(propId.descriptor) is true.
                //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                var currentKind = void 0;
                if (prop.kind === 261 /* PropertyAssignment */ || prop.kind === 262 /* ShorthandPropertyAssignment */) {
                    // Grammar checking for computedPropertyName and shorthandPropertyAssignment
                    checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                    if (name.kind === 8 /* NumericLiteral */) {
                        checkGrammarNumericLiteral(name);
                    }
                    currentKind = Property;
                }
                else if (prop.kind === 151 /* MethodDeclaration */) {
                    currentKind = Property;
                }
                else if (prop.kind === 153 /* GetAccessor */) {
                    currentKind = GetAccessor;
                }
                else if (prop.kind === 154 /* SetAccessor */) {
                    currentKind = SetAccessor;
                }
                else {
                    ts.Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind);
                }
                var effectiveName = ts.getPropertyNameForPropertyNameNode(name);
                if (effectiveName === undefined) {
                    continue;
                }
                var existingKind = seen.get(effectiveName);
                if (!existingKind) {
                    seen.set(effectiveName, currentKind);
                }
                else {
                    if (currentKind === Property && existingKind === Property) {
                        grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name));
                    }
                    else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
                        if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
                            seen.set(effectiveName, currentKind | existingKind);
                        }
                        else {
                            return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
                        }
                    }
                    else {
                        return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
                    }
                }
            }
        }
        function checkGrammarJsxElement(node) {
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.attributes.properties; _i < _a.length; _i++) {
                var attr = _a[_i];
                if (attr.kind === 255 /* JsxSpreadAttribute */) {
                    continue;
                }
                var jsxAttr = attr;
                var name = jsxAttr.name;
                if (!seen.get(name.escapedText)) {
                    seen.set(name.escapedText, true);
                }
                else {
                    return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
                }
                var initializer = jsxAttr.initializer;
                if (initializer && initializer.kind === 256 /* JsxExpression */ && !initializer.expression) {
                    return grammarErrorOnNode(jsxAttr.initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
                }
            }
        }
        function checkGrammarForInOrForOfStatement(forInOrOfStatement) {
            if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
                return true;
            }
            if (forInOrOfStatement.kind === 216 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) {
                if ((forInOrOfStatement.flags & 16384 /* AwaitContext */) === 0 /* None */) {
                    return grammarErrorOnNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator);
                }
            }
            if (forInOrOfStatement.initializer.kind === 227 /* VariableDeclarationList */) {
                var variableList = forInOrOfStatement.initializer;
                if (!checkGrammarVariableDeclarationList(variableList)) {
                    var declarations = variableList.declarations;
                    // declarations.length can be zero if there is an error in variable declaration in for-of or for-in
                    // See http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements for details
                    // For example:
                    //      var let = 10;
                    //      for (let of [1,2,3]) {} // this is invalid ES6 syntax
                    //      for (let in [1,2,3]) {} // this is invalid ES6 syntax
                    // We will then want to skip on grammar checking on variableList declaration
                    if (!declarations.length) {
                        return false;
                    }
                    if (declarations.length > 1) {
                        var diagnostic = forInOrOfStatement.kind === 215 /* ForInStatement */
                            ? ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
                            : ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
                        return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
                    }
                    var firstDeclaration = declarations[0];
                    if (firstDeclaration.initializer) {
                        var diagnostic = forInOrOfStatement.kind === 215 /* ForInStatement */
                            ? ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
                            : ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
                        return grammarErrorOnNode(firstDeclaration.name, diagnostic);
                    }
                    if (firstDeclaration.type) {
                        var diagnostic = forInOrOfStatement.kind === 215 /* ForInStatement */
                            ? ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
                            : ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
                        return grammarErrorOnNode(firstDeclaration, diagnostic);
                    }
                }
            }
            return false;
        }
        function checkGrammarAccessor(accessor) {
            var kind = accessor.kind;
            if (languageVersion < 1 /* ES5 */) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
            }
            else if (ts.isInAmbientContext(accessor)) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
            }
            else if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) {
                return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
            }
            else if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) {
                return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
            }
            else if (accessor.typeParameters) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters);
            }
            else if (!doesAccessorHaveCorrectParameterCount(accessor)) {
                return grammarErrorOnNode(accessor.name, kind === 153 /* GetAccessor */ ?
                    ts.Diagnostics.A_get_accessor_cannot_have_parameters :
                    ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
            }
            else if (kind === 154 /* SetAccessor */) {
                if (accessor.type) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
                }
                else {
                    var parameter = accessor.parameters[0];
                    if (parameter.dotDotDotToken) {
                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter);
                    }
                    else if (parameter.questionToken) {
                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
                    }
                    else if (parameter.initializer) {
                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
                    }
                }
            }
        }
        /** Does the accessor have the right number of parameters?
         * A get accessor has no parameters or a single `this` parameter.
         * A set accessor has one parameter or a `this` parameter and one more parameter.
         */
        function doesAccessorHaveCorrectParameterCount(accessor) {
            return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === 153 /* GetAccessor */ ? 0 : 1);
        }
        function getAccessorThisParameter(accessor) {
            if (accessor.parameters.length === (accessor.kind === 153 /* GetAccessor */ ? 1 : 2)) {
                return ts.getThisParameter(accessor);
            }
        }
        function checkGrammarForNonSymbolComputedProperty(node, message) {
            if (ts.isDynamicName(node)) {
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarMethod(node) {
            if (checkGrammarDisallowedModifiersOnObjectLiteralExpressionMethod(node) ||
                checkGrammarFunctionLikeDeclaration(node) ||
                checkGrammarForGenerator(node)) {
                return true;
            }
            if (node.parent.kind === 178 /* ObjectLiteralExpression */) {
                if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) {
                    return true;
                }
                else if (node.body === undefined) {
                    return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                }
            }
            if (ts.isClassLike(node.parent)) {
                // Technically, computed properties in ambient contexts is disallowed
                // for property declarations and accessors too, not just methods.
                // However, property declarations disallow computed names in general,
                // and accessors are not allowed in ambient contexts in general,
                // so this error only really matters for methods.
                if (ts.isInAmbientContext(node)) {
                    return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol);
                }
                else if (!node.body) {
                    return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol);
                }
            }
            else if (node.parent.kind === 230 /* InterfaceDeclaration */) {
                return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol);
            }
            else if (node.parent.kind === 163 /* TypeLiteral */) {
                return checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol);
            }
        }
        function checkGrammarBreakOrContinueStatement(node) {
            var current = node;
            while (current) {
                if (ts.isFunctionLike(current)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary);
                }
                switch (current.kind) {
                    case 222 /* LabeledStatement */:
                        if (node.label && current.label.escapedText === node.label.escapedText) {
                            // found matching label - verify that label usage is correct
                            // continue can only target labels that are on iteration statements
                            var isMisplacedContinueLabel = node.kind === 217 /* ContinueStatement */
                                && !ts.isIterationStatement(current.statement, /*lookInLabeledStatement*/ true);
                            if (isMisplacedContinueLabel) {
                                return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
                            }
                            return false;
                        }
                        break;
                    case 221 /* SwitchStatement */:
                        if (node.kind === 218 /* BreakStatement */ && !node.label) {
                            // unlabeled break within switch statement - ok
                            return false;
                        }
                        break;
                    default:
                        if (ts.isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) {
                            // unlabeled break or continue within iteration statement - ok
                            return false;
                        }
                        break;
                }
                current = current.parent;
            }
            if (node.label) {
                var message = node.kind === 218 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement
                    : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
            else {
                var message = node.kind === 218 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement
                    : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarBindingElement(node) {
            if (node.dotDotDotToken) {
                var elements = node.parent.elements;
                if (node !== ts.lastOrUndefined(elements)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                if (node.name.kind === 175 /* ArrayBindingPattern */ || node.name.kind === 174 /* ObjectBindingPattern */) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
                }
                if (node.initializer) {
                    // Error on equals token which immediately precedes the initializer
                    return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                }
            }
        }
        function isStringOrNumberLiteralExpression(expr) {
            return expr.kind === 9 /* StringLiteral */ || expr.kind === 8 /* NumericLiteral */ ||
                expr.kind === 192 /* PrefixUnaryExpression */ && expr.operator === 38 /* MinusToken */ &&
                    expr.operand.kind === 8 /* NumericLiteral */;
        }
        function checkGrammarVariableDeclaration(node) {
            if (node.parent.parent.kind !== 215 /* ForInStatement */ && node.parent.parent.kind !== 216 /* ForOfStatement */) {
                if (ts.isInAmbientContext(node)) {
                    if (node.initializer) {
                        if (ts.isConst(node) && !node.type) {
                            if (!isStringOrNumberLiteralExpression(node.initializer)) {
                                return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal);
                            }
                        }
                        else {
                            // Error on equals token which immediate precedes the initializer
                            var equalsTokenLength = "=".length;
                            return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                        }
                    }
                    if (node.initializer && !(ts.isConst(node) && isStringOrNumberLiteralExpression(node.initializer))) {
                        // Error on equals token which immediate precedes the initializer
                        var equalsTokenLength = "=".length;
                        return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                    }
                }
                else if (!node.initializer) {
                    if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer);
                    }
                    if (ts.isConst(node)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized);
                    }
                }
            }
            if (compilerOptions.module !== ts.ModuleKind.ES2015 && compilerOptions.module !== ts.ModuleKind.ESNext && compilerOptions.module !== ts.ModuleKind.System && !compilerOptions.noEmit &&
                !ts.isInAmbientContext(node.parent.parent) && ts.hasModifier(node.parent.parent, 1 /* Export */)) {
                checkESModuleMarker(node.name);
            }
            var checkLetConstNames = (ts.isLet(node) || ts.isConst(node));
            // 1. LexicalDeclaration : LetOrConst BindingList ;
            // It is a Syntax Error if the BoundNames of BindingList contains "let".
            // 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding
            // It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
            // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
            // and its Identifier is eval or arguments
            return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
        }
        function checkESModuleMarker(name) {
            if (name.kind === 71 /* Identifier */) {
                if (ts.idText(name) === "__esModule") {
                    return grammarErrorOnNode(name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                    var element = elements_1[_i];
                    if (!ts.isOmittedExpression(element)) {
                        return checkESModuleMarker(element.name);
                    }
                }
            }
        }
        function checkGrammarNameInLetOrConstDeclarations(name) {
            if (name.kind === 71 /* Identifier */) {
                if (name.originalKeywordKind === 110 /* LetKeyword */) {
                    return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
                    var element = elements_2[_i];
                    if (!ts.isOmittedExpression(element)) {
                        checkGrammarNameInLetOrConstDeclarations(element.name);
                    }
                }
            }
        }
        function checkGrammarVariableDeclarationList(declarationList) {
            var declarations = declarationList.declarations;
            if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
                return true;
            }
            if (!declarationList.declarations.length) {
                return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
            }
        }
        function allowLetAndConstDeclarations(parent) {
            switch (parent.kind) {
                case 211 /* IfStatement */:
                case 212 /* DoStatement */:
                case 213 /* WhileStatement */:
                case 220 /* WithStatement */:
                case 214 /* ForStatement */:
                case 215 /* ForInStatement */:
                case 216 /* ForOfStatement */:
                    return false;
                case 222 /* LabeledStatement */:
                    return allowLetAndConstDeclarations(parent.parent);
            }
            return true;
        }
        function checkGrammarForDisallowedLetOrConstStatement(node) {
            if (!allowLetAndConstDeclarations(node.parent)) {
                if (ts.isLet(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
                }
                else if (ts.isConst(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
                }
            }
        }
        function checkGrammarMetaProperty(node) {
            if (node.keywordToken === 94 /* NewKeyword */) {
                if (node.name.escapedText !== "target") {
                    return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target");
                }
            }
        }
        function hasParseDiagnostics(sourceFile) {
            return sourceFile.parseDiagnostics.length > 0;
        }
        function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span_4 = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, span_4.start, span_4.length, message, arg0, arg1, arg2));
                return true;
            }
        }
        function grammarErrorAtPos(nodeForSourceFile, start, length, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(nodeForSourceFile);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
                return true;
            }
        }
        function grammarErrorOnNode(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2));
                return true;
            }
        }
        function checkGrammarConstructorTypeParameters(node) {
            if (node.typeParameters) {
                return grammarErrorAtPos(node, node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarConstructorTypeAnnotation(node) {
            if (node.type) {
                return grammarErrorOnNode(node.type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarProperty(node) {
            if (ts.isClassLike(node.parent)) {
                if (checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) {
                    return true;
                }
            }
            else if (node.parent.kind === 230 /* InterfaceDeclaration */) {
                if (checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer);
                }
            }
            else if (node.parent.kind === 163 /* TypeLiteral */) {
                if (checkGrammarForNonSymbolComputedProperty(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer);
                }
            }
            if (ts.isInAmbientContext(node) && node.initializer) {
                return grammarErrorOnFirstToken(node.initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
            }
        }
        function checkGrammarTopLevelElementForRequiredDeclareModifier(node) {
            // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace
            // interfaces and imports categories:
            //
            //  DeclarationElement:
            //     ExportAssignment
            //     export_opt   InterfaceDeclaration
            //     export_opt   TypeAliasDeclaration
            //     export_opt   ImportDeclaration
            //     export_opt   ExternalImportDeclaration
            //     export_opt   AmbientDeclaration
            //
            // TODO: The spec needs to be amended to reflect this grammar.
            if (node.kind === 230 /* InterfaceDeclaration */ ||
                node.kind === 231 /* TypeAliasDeclaration */ ||
                node.kind === 238 /* ImportDeclaration */ ||
                node.kind === 237 /* ImportEqualsDeclaration */ ||
                node.kind === 244 /* ExportDeclaration */ ||
                node.kind === 243 /* ExportAssignment */ ||
                node.kind === 236 /* NamespaceExportDeclaration */ ||
                ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) {
                return false;
            }
            return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file);
        }
        function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) {
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (ts.isDeclaration(decl) || decl.kind === 208 /* VariableStatement */) {
                    if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) {
                        return true;
                    }
                }
            }
        }
        function checkGrammarSourceFile(node) {
            return ts.isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
        }
        function checkGrammarStatementInAmbientContext(node) {
            if (ts.isInAmbientContext(node)) {
                // An accessors is already reported about the ambient context
                if (ts.isAccessor(node.parent)) {
                    return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
                }
                // Find containing block which is either Block, ModuleBlock, SourceFile
                var links = getNodeLinks(node);
                if (!links.hasReportedStatementInAmbientContext && ts.isFunctionLike(node.parent)) {
                    return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
                }
                // We are either parented by another statement, or some sort of block.
                // If we're in a block, we only want to really report an error once
                // to prevent noisiness.  So use a bit on the block to indicate if
                // this has already been reported, and don't report if it has.
                //
                if (node.parent.kind === 207 /* Block */ || node.parent.kind === 234 /* ModuleBlock */ || node.parent.kind === 265 /* SourceFile */) {
                    var links_1 = getNodeLinks(node.parent);
                    // Check if the containing block ever report this error
                    if (!links_1.hasReportedStatementInAmbientContext) {
                        return links_1.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
                    }
                }
                else {
                    // We must be parented by a statement.  If so, there's no need
                    // to report the error as our parent will have already done it.
                    // Debug.assert(isStatement(node.parent));
                }
            }
        }
        function checkGrammarNumericLiteral(node) {
            // Grammar checking
            if (node.numericLiteralFlags & 4 /* Octal */) {
                var diagnosticMessage = void 0;
                if (languageVersion >= 1 /* ES5 */) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 173 /* LiteralType */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 264 /* EnumMember */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0;
                }
                if (diagnosticMessage) {
                    var withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 38 /* MinusToken */;
                    var literal = (withMinus ? "-" : "") + "0o" + node.text;
                    return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
                }
            }
        }
        function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span_5 = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span_5), /*length*/ 0, message, arg0, arg1, arg2));
                return true;
            }
        }
        function getAmbientModules() {
            if (!ambientModulesCache) {
                ambientModulesCache = [];
                globals.forEach(function (global, sym) {
                    // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module.
                    if (ambientModuleSymbolRegex.test(sym)) {
                        ambientModulesCache.push(global);
                    }
                });
            }
            return ambientModulesCache;
        }
        function checkGrammarImportCallExpression(node) {
            if (modulekind === ts.ModuleKind.ES2015) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
            }
            if (node.typeArguments) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_have_type_arguments);
            }
            var nodeArguments = node.arguments;
            if (nodeArguments.length !== 1) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
            }
            // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
            // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
            if (ts.isSpreadElement(nodeArguments[0])) {
                return grammarErrorOnNode(nodeArguments[0], ts.Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
            }
        }
    }
    ts.createTypeChecker = createTypeChecker;
    /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
    function isDeclarationNameOrImportPropertyName(name) {
        switch (name.parent.kind) {
            case 242 /* ImportSpecifier */:
            case 246 /* ExportSpecifier */:
                return true;
            default:
                return ts.isDeclarationName(name);
        }
    }
    function isSomeImportDeclaration(decl) {
        switch (decl.kind) {
            case 239 /* ImportClause */: // For default import
            case 237 /* ImportEqualsDeclaration */:
            case 240 /* NamespaceImport */:
            case 242 /* ImportSpecifier */:// For rename import `x as y`
                return true;
            case 71 /* Identifier */:
                // For regular import, `decl` is an Identifier under the ImportSpecifier.
                return decl.parent.kind === 242 /* ImportSpecifier */;
            default:
                return false;
        }
    }
})(ts || (ts = {}));
/// <reference path="core.ts"/>
/// <reference path="utilities.ts"/>
var ts;
(function (ts) {
    function createSynthesizedNode(kind) {
        var node = ts.createNode(kind, -1, -1);
        node.flags |= 8 /* Synthesized */;
        return node;
    }
    /* @internal */
    function updateNode(updated, original) {
        if (updated !== original) {
            setOriginalNode(updated, original);
            setTextRange(updated, original);
            if (original.startsOnNewLine) {
                updated.startsOnNewLine = true;
            }
            ts.aggregateTransformFlags(updated);
        }
        return updated;
    }
    ts.updateNode = updateNode;
    /**
     * Make `elements` into a `NodeArray<T>`. If `elements` is `undefined`, returns an empty `NodeArray<T>`.
     */
    function createNodeArray(elements, hasTrailingComma) {
        if (elements) {
            if (ts.isNodeArray(elements)) {
                return elements;
            }
        }
        else {
            elements = [];
        }
        var array = elements;
        array.pos = -1;
        array.end = -1;
        array.hasTrailingComma = hasTrailingComma;
        return array;
    }
    ts.createNodeArray = createNodeArray;
    /**
     * Creates a shallow, memberwise clone of a node with no source map location.
     */
    /* @internal */
    function getSynthesizedClone(node) {
        // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
        // the original node. We also need to exclude specific properties and only include own-
        // properties (to skip members already defined on the shared prototype).
        if (node === undefined) {
            return undefined;
        }
        var clone = createSynthesizedNode(node.kind);
        clone.flags |= node.flags;
        setOriginalNode(clone, node);
        for (var key in node) {
            if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
                continue;
            }
            clone[key] = node[key];
        }
        return clone;
    }
    ts.getSynthesizedClone = getSynthesizedClone;
    function createLiteral(value) {
        if (typeof value === "number") {
            return createNumericLiteral(value + "");
        }
        if (typeof value === "boolean") {
            return value ? createTrue() : createFalse();
        }
        if (ts.isString(value)) {
            return createStringLiteral(value);
        }
        return createLiteralFromNode(value);
    }
    ts.createLiteral = createLiteral;
    function createNumericLiteral(value) {
        var node = createSynthesizedNode(8 /* NumericLiteral */);
        node.text = value;
        node.numericLiteralFlags = 0;
        return node;
    }
    ts.createNumericLiteral = createNumericLiteral;
    function createStringLiteral(text) {
        var node = createSynthesizedNode(9 /* StringLiteral */);
        node.text = text;
        return node;
    }
    function createLiteralFromNode(sourceNode) {
        var node = createStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode));
        node.textSourceNode = sourceNode;
        return node;
    }
    function createIdentifier(text, typeArguments) {
        var node = createSynthesizedNode(71 /* Identifier */);
        node.escapedText = ts.escapeLeadingUnderscores(text);
        node.originalKeywordKind = text ? ts.stringToToken(text) : 0 /* Unknown */;
        node.autoGenerateKind = 0 /* None */;
        node.autoGenerateId = 0;
        if (typeArguments) {
            node.typeArguments = createNodeArray(typeArguments);
        }
        return node;
    }
    ts.createIdentifier = createIdentifier;
    function updateIdentifier(node, typeArguments) {
        return node.typeArguments !== typeArguments
            ? updateNode(createIdentifier(ts.idText(node), typeArguments), node)
            : node;
    }
    ts.updateIdentifier = updateIdentifier;
    var nextAutoGenerateId = 0;
    /** Create a unique temporary variable. */
    function createTempVariable(recordTempVariable) {
        var name = createIdentifier("");
        name.autoGenerateKind = 1 /* Auto */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        if (recordTempVariable) {
            recordTempVariable(name);
        }
        return name;
    }
    ts.createTempVariable = createTempVariable;
    /** Create a unique temporary variable for use in a loop. */
    function createLoopVariable() {
        var name = createIdentifier("");
        name.autoGenerateKind = 2 /* Loop */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createLoopVariable = createLoopVariable;
    /** Create a unique name based on the supplied text. */
    function createUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateKind = 3 /* Unique */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createUniqueName = createUniqueName;
    /** Create a unique name generated for a node. */
    function getGeneratedNameForNode(node) {
        var name = createIdentifier("");
        name.autoGenerateKind = 4 /* Node */;
        name.autoGenerateId = nextAutoGenerateId;
        name.original = node;
        nextAutoGenerateId++;
        return name;
    }
    ts.getGeneratedNameForNode = getGeneratedNameForNode;
    // Punctuation
    function createToken(token) {
        return createSynthesizedNode(token);
    }
    ts.createToken = createToken;
    // Reserved words
    function createSuper() {
        return createSynthesizedNode(97 /* SuperKeyword */);
    }
    ts.createSuper = createSuper;
    function createThis() {
        return createSynthesizedNode(99 /* ThisKeyword */);
    }
    ts.createThis = createThis;
    function createNull() {
        return createSynthesizedNode(95 /* NullKeyword */);
    }
    ts.createNull = createNull;
    function createTrue() {
        return createSynthesizedNode(101 /* TrueKeyword */);
    }
    ts.createTrue = createTrue;
    function createFalse() {
        return createSynthesizedNode(86 /* FalseKeyword */);
    }
    ts.createFalse = createFalse;
    // Names
    function createQualifiedName(left, right) {
        var node = createSynthesizedNode(143 /* QualifiedName */);
        node.left = left;
        node.right = asName(right);
        return node;
    }
    ts.createQualifiedName = createQualifiedName;
    function updateQualifiedName(node, left, right) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createQualifiedName(left, right), node)
            : node;
    }
    ts.updateQualifiedName = updateQualifiedName;
    function createComputedPropertyName(expression) {
        var node = createSynthesizedNode(144 /* ComputedPropertyName */);
        node.expression = expression;
        return node;
    }
    ts.createComputedPropertyName = createComputedPropertyName;
    function updateComputedPropertyName(node, expression) {
        return node.expression !== expression
            ? updateNode(createComputedPropertyName(expression), node)
            : node;
    }
    ts.updateComputedPropertyName = updateComputedPropertyName;
    // Signature elements
    function createTypeParameterDeclaration(name, constraint, defaultType) {
        var node = createSynthesizedNode(145 /* TypeParameter */);
        node.name = asName(name);
        node.constraint = constraint;
        node.default = defaultType;
        return node;
    }
    ts.createTypeParameterDeclaration = createTypeParameterDeclaration;
    function updateTypeParameterDeclaration(node, name, constraint, defaultType) {
        return node.name !== name
            || node.constraint !== constraint
            || node.default !== defaultType
            ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
            : node;
    }
    ts.updateTypeParameterDeclaration = updateTypeParameterDeclaration;
    function createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(146 /* Parameter */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.dotDotDotToken = dotDotDotToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createParameter = createParameter;
    function updateParameter(node, decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updateParameter = updateParameter;
    function createDecorator(expression) {
        var node = createSynthesizedNode(147 /* Decorator */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createDecorator = createDecorator;
    function updateDecorator(node, expression) {
        return node.expression !== expression
            ? updateNode(createDecorator(expression), node)
            : node;
    }
    ts.updateDecorator = updateDecorator;
    // Type Elements
    function createPropertySignature(modifiers, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(148 /* PropertySignature */);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createPropertySignature = createPropertySignature;
    function updatePropertySignature(node, modifiers, name, questionToken, type, initializer) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updatePropertySignature = updatePropertySignature;
    function createProperty(decorators, modifiers, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(149 /* PropertyDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createProperty = createProperty;
    function updateProperty(node, decorators, modifiers, name, questionToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createProperty(decorators, modifiers, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updateProperty = updateProperty;
    function createMethodSignature(typeParameters, parameters, type, name, questionToken) {
        var node = createSignatureDeclaration(150 /* MethodSignature */, typeParameters, parameters, type);
        node.name = asName(name);
        node.questionToken = questionToken;
        return node;
    }
    ts.createMethodSignature = createMethodSignature;
    function updateMethodSignature(node, typeParameters, parameters, type, name, questionToken) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.name !== name
            || node.questionToken !== questionToken
            ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
            : node;
    }
    ts.updateMethodSignature = updateMethodSignature;
    function createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(151 /* MethodDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createMethod = createMethod;
    function updateMethod(node, decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateMethod = updateMethod;
    function createConstructor(decorators, modifiers, parameters, body) {
        var node = createSynthesizedNode(152 /* Constructor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = undefined;
        node.body = body;
        return node;
    }
    ts.createConstructor = createConstructor;
    function updateConstructor(node, decorators, modifiers, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createConstructor(decorators, modifiers, parameters, body), node)
            : node;
    }
    ts.updateConstructor = updateConstructor;
    function createGetAccessor(decorators, modifiers, name, parameters, type, body) {
        var node = createSynthesizedNode(153 /* GetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createGetAccessor = createGetAccessor;
    function updateGetAccessor(node, decorators, modifiers, name, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node)
            : node;
    }
    ts.updateGetAccessor = updateGetAccessor;
    function createSetAccessor(decorators, modifiers, name, parameters, body) {
        var node = createSynthesizedNode(154 /* SetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.body = body;
        return node;
    }
    ts.createSetAccessor = createSetAccessor;
    function updateSetAccessor(node, decorators, modifiers, name, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node)
            : node;
    }
    ts.updateSetAccessor = updateSetAccessor;
    function createCallSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(155 /* CallSignature */, typeParameters, parameters, type);
    }
    ts.createCallSignature = createCallSignature;
    function updateCallSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateCallSignature = updateCallSignature;
    function createConstructSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(156 /* ConstructSignature */, typeParameters, parameters, type);
    }
    ts.createConstructSignature = createConstructSignature;
    function updateConstructSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructSignature = updateConstructSignature;
    function createIndexSignature(decorators, modifiers, parameters, type) {
        var node = createSynthesizedNode(157 /* IndexSignature */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        return node;
    }
    ts.createIndexSignature = createIndexSignature;
    function updateIndexSignature(node, decorators, modifiers, parameters, type) {
        return node.parameters !== parameters
            || node.type !== type
            || node.decorators !== decorators
            || node.modifiers !== modifiers
            ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node)
            : node;
    }
    ts.updateIndexSignature = updateIndexSignature;
    /* @internal */
    function createSignatureDeclaration(kind, typeParameters, parameters, type) {
        var node = createSynthesizedNode(kind);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = asNodeArray(parameters);
        node.type = type;
        return node;
    }
    ts.createSignatureDeclaration = createSignatureDeclaration;
    function updateSignatureDeclaration(node, typeParameters, parameters, type) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
            : node;
    }
    // Types
    function createKeywordTypeNode(kind) {
        return createSynthesizedNode(kind);
    }
    ts.createKeywordTypeNode = createKeywordTypeNode;
    function createTypePredicateNode(parameterName, type) {
        var node = createSynthesizedNode(158 /* TypePredicate */);
        node.parameterName = asName(parameterName);
        node.type = type;
        return node;
    }
    ts.createTypePredicateNode = createTypePredicateNode;
    function updateTypePredicateNode(node, parameterName, type) {
        return node.parameterName !== parameterName
            || node.type !== type
            ? updateNode(createTypePredicateNode(parameterName, type), node)
            : node;
    }
    ts.updateTypePredicateNode = updateTypePredicateNode;
    function createTypeReferenceNode(typeName, typeArguments) {
        var node = createSynthesizedNode(159 /* TypeReference */);
        node.typeName = asName(typeName);
        node.typeArguments = typeArguments && ts.parenthesizeTypeParameters(typeArguments);
        return node;
    }
    ts.createTypeReferenceNode = createTypeReferenceNode;
    function updateTypeReferenceNode(node, typeName, typeArguments) {
        return node.typeName !== typeName
            || node.typeArguments !== typeArguments
            ? updateNode(createTypeReferenceNode(typeName, typeArguments), node)
            : node;
    }
    ts.updateTypeReferenceNode = updateTypeReferenceNode;
    function createFunctionTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(160 /* FunctionType */, typeParameters, parameters, type);
    }
    ts.createFunctionTypeNode = createFunctionTypeNode;
    function updateFunctionTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateFunctionTypeNode = updateFunctionTypeNode;
    function createConstructorTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(161 /* ConstructorType */, typeParameters, parameters, type);
    }
    ts.createConstructorTypeNode = createConstructorTypeNode;
    function updateConstructorTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructorTypeNode = updateConstructorTypeNode;
    function createTypeQueryNode(exprName) {
        var node = createSynthesizedNode(162 /* TypeQuery */);
        node.exprName = exprName;
        return node;
    }
    ts.createTypeQueryNode = createTypeQueryNode;
    function updateTypeQueryNode(node, exprName) {
        return node.exprName !== exprName
            ? updateNode(createTypeQueryNode(exprName), node)
            : node;
    }
    ts.updateTypeQueryNode = updateTypeQueryNode;
    function createTypeLiteralNode(members) {
        var node = createSynthesizedNode(163 /* TypeLiteral */);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createTypeLiteralNode = createTypeLiteralNode;
    function updateTypeLiteralNode(node, members) {
        return node.members !== members
            ? updateNode(createTypeLiteralNode(members), node)
            : node;
    }
    ts.updateTypeLiteralNode = updateTypeLiteralNode;
    function createArrayTypeNode(elementType) {
        var node = createSynthesizedNode(164 /* ArrayType */);
        node.elementType = ts.parenthesizeArrayTypeMember(elementType);
        return node;
    }
    ts.createArrayTypeNode = createArrayTypeNode;
    function updateArrayTypeNode(node, elementType) {
        return node.elementType !== elementType
            ? updateNode(createArrayTypeNode(elementType), node)
            : node;
    }
    ts.updateArrayTypeNode = updateArrayTypeNode;
    function createTupleTypeNode(elementTypes) {
        var node = createSynthesizedNode(165 /* TupleType */);
        node.elementTypes = createNodeArray(elementTypes);
        return node;
    }
    ts.createTupleTypeNode = createTupleTypeNode;
    function updateTypleTypeNode(node, elementTypes) {
        return node.elementTypes !== elementTypes
            ? updateNode(createTupleTypeNode(elementTypes), node)
            : node;
    }
    ts.updateTypleTypeNode = updateTypleTypeNode;
    function createUnionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(166 /* UnionType */, types);
    }
    ts.createUnionTypeNode = createUnionTypeNode;
    function updateUnionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateUnionTypeNode = updateUnionTypeNode;
    function createIntersectionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(167 /* IntersectionType */, types);
    }
    ts.createIntersectionTypeNode = createIntersectionTypeNode;
    function updateIntersectionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateIntersectionTypeNode = updateIntersectionTypeNode;
    function createUnionOrIntersectionTypeNode(kind, types) {
        var node = createSynthesizedNode(kind);
        node.types = ts.parenthesizeElementTypeMembers(types);
        return node;
    }
    ts.createUnionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode;
    function updateUnionOrIntersectionTypeNode(node, types) {
        return node.types !== types
            ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node)
            : node;
    }
    function createParenthesizedType(type) {
        var node = createSynthesizedNode(168 /* ParenthesizedType */);
        node.type = type;
        return node;
    }
    ts.createParenthesizedType = createParenthesizedType;
    function updateParenthesizedType(node, type) {
        return node.type !== type
            ? updateNode(createParenthesizedType(type), node)
            : node;
    }
    ts.updateParenthesizedType = updateParenthesizedType;
    function createThisTypeNode() {
        return createSynthesizedNode(169 /* ThisType */);
    }
    ts.createThisTypeNode = createThisTypeNode;
    function createTypeOperatorNode(type) {
        var node = createSynthesizedNode(170 /* TypeOperator */);
        node.operator = 127 /* KeyOfKeyword */;
        node.type = ts.parenthesizeElementTypeMember(type);
        return node;
    }
    ts.createTypeOperatorNode = createTypeOperatorNode;
    function updateTypeOperatorNode(node, type) {
        return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node;
    }
    ts.updateTypeOperatorNode = updateTypeOperatorNode;
    function createIndexedAccessTypeNode(objectType, indexType) {
        var node = createSynthesizedNode(171 /* IndexedAccessType */);
        node.objectType = ts.parenthesizeElementTypeMember(objectType);
        node.indexType = indexType;
        return node;
    }
    ts.createIndexedAccessTypeNode = createIndexedAccessTypeNode;
    function updateIndexedAccessTypeNode(node, objectType, indexType) {
        return node.objectType !== objectType
            || node.indexType !== indexType
            ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node)
            : node;
    }
    ts.updateIndexedAccessTypeNode = updateIndexedAccessTypeNode;
    function createMappedTypeNode(readonlyToken, typeParameter, questionToken, type) {
        var node = createSynthesizedNode(172 /* MappedType */);
        node.readonlyToken = readonlyToken;
        node.typeParameter = typeParameter;
        node.questionToken = questionToken;
        node.type = type;
        return node;
    }
    ts.createMappedTypeNode = createMappedTypeNode;
    function updateMappedTypeNode(node, readonlyToken, typeParameter, questionToken, type) {
        return node.readonlyToken !== readonlyToken
            || node.typeParameter !== typeParameter
            || node.questionToken !== questionToken
            || node.type !== type
            ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
            : node;
    }
    ts.updateMappedTypeNode = updateMappedTypeNode;
    function createLiteralTypeNode(literal) {
        var node = createSynthesizedNode(173 /* LiteralType */);
        node.literal = literal;
        return node;
    }
    ts.createLiteralTypeNode = createLiteralTypeNode;
    function updateLiteralTypeNode(node, literal) {
        return node.literal !== literal
            ? updateNode(createLiteralTypeNode(literal), node)
            : node;
    }
    ts.updateLiteralTypeNode = updateLiteralTypeNode;
    // Binding Patterns
    function createObjectBindingPattern(elements) {
        var node = createSynthesizedNode(174 /* ObjectBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createObjectBindingPattern = createObjectBindingPattern;
    function updateObjectBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createObjectBindingPattern(elements), node)
            : node;
    }
    ts.updateObjectBindingPattern = updateObjectBindingPattern;
    function createArrayBindingPattern(elements) {
        var node = createSynthesizedNode(175 /* ArrayBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createArrayBindingPattern = createArrayBindingPattern;
    function updateArrayBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayBindingPattern(elements), node)
            : node;
    }
    ts.updateArrayBindingPattern = updateArrayBindingPattern;
    function createBindingElement(dotDotDotToken, propertyName, name, initializer) {
        var node = createSynthesizedNode(176 /* BindingElement */);
        node.dotDotDotToken = dotDotDotToken;
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        node.initializer = initializer;
        return node;
    }
    ts.createBindingElement = createBindingElement;
    function updateBindingElement(node, dotDotDotToken, propertyName, name, initializer) {
        return node.propertyName !== propertyName
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.initializer !== initializer
            ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
            : node;
    }
    ts.updateBindingElement = updateBindingElement;
    // Expression
    function createArrayLiteral(elements, multiLine) {
        var node = createSynthesizedNode(177 /* ArrayLiteralExpression */);
        node.elements = ts.parenthesizeListElements(createNodeArray(elements));
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createArrayLiteral = createArrayLiteral;
    function updateArrayLiteral(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayLiteral(elements, node.multiLine), node)
            : node;
    }
    ts.updateArrayLiteral = updateArrayLiteral;
    function createObjectLiteral(properties, multiLine) {
        var node = createSynthesizedNode(178 /* ObjectLiteralExpression */);
        node.properties = createNodeArray(properties);
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createObjectLiteral = createObjectLiteral;
    function updateObjectLiteral(node, properties) {
        return node.properties !== properties
            ? updateNode(createObjectLiteral(properties, node.multiLine), node)
            : node;
    }
    ts.updateObjectLiteral = updateObjectLiteral;
    function createPropertyAccess(expression, name) {
        var node = createSynthesizedNode(179 /* PropertyAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.name = asName(name);
        setEmitFlags(node, 131072 /* NoIndentation */);
        return node;
    }
    ts.createPropertyAccess = createPropertyAccess;
    function updatePropertyAccess(node, expression, name) {
        // Because we are updating existed propertyAccess we want to inherit its emitFlags
        // instead of using the default from createPropertyAccess
        return node.expression !== expression
            || node.name !== name
            ? updateNode(setEmitFlags(createPropertyAccess(expression, name), ts.getEmitFlags(node)), node)
            : node;
    }
    ts.updatePropertyAccess = updatePropertyAccess;
    function createElementAccess(expression, index) {
        var node = createSynthesizedNode(180 /* ElementAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.argumentExpression = asExpression(index);
        return node;
    }
    ts.createElementAccess = createElementAccess;
    function updateElementAccess(node, expression, argumentExpression) {
        return node.expression !== expression
            || node.argumentExpression !== argumentExpression
            ? updateNode(createElementAccess(expression, argumentExpression), node)
            : node;
    }
    ts.updateElementAccess = updateElementAccess;
    function createCall(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(181 /* CallExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
        return node;
    }
    ts.createCall = createCall;
    function updateCall(node, expression, typeArguments, argumentsArray) {
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createCall(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateCall = updateCall;
    function createNew(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(182 /* NewExpression */);
        node.expression = ts.parenthesizeForNew(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = argumentsArray ? ts.parenthesizeListElements(createNodeArray(argumentsArray)) : undefined;
        return node;
    }
    ts.createNew = createNew;
    function updateNew(node, expression, typeArguments, argumentsArray) {
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createNew(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateNew = updateNew;
    function createTaggedTemplate(tag, template) {
        var node = createSynthesizedNode(183 /* TaggedTemplateExpression */);
        node.tag = ts.parenthesizeForAccess(tag);
        node.template = template;
        return node;
    }
    ts.createTaggedTemplate = createTaggedTemplate;
    function updateTaggedTemplate(node, tag, template) {
        return node.tag !== tag
            || node.template !== template
            ? updateNode(createTaggedTemplate(tag, template), node)
            : node;
    }
    ts.updateTaggedTemplate = updateTaggedTemplate;
    function createTypeAssertion(type, expression) {
        var node = createSynthesizedNode(184 /* TypeAssertionExpression */);
        node.type = type;
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeAssertion = createTypeAssertion;
    function updateTypeAssertion(node, type, expression) {
        return node.type !== type
            || node.expression !== expression
            ? updateNode(createTypeAssertion(type, expression), node)
            : node;
    }
    ts.updateTypeAssertion = updateTypeAssertion;
    function createParen(expression) {
        var node = createSynthesizedNode(185 /* ParenthesizedExpression */);
        node.expression = expression;
        return node;
    }
    ts.createParen = createParen;
    function updateParen(node, expression) {
        return node.expression !== expression
            ? updateNode(createParen(expression), node)
            : node;
    }
    ts.updateParen = updateParen;
    function createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(186 /* FunctionExpression */);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionExpression = createFunctionExpression;
    function updateFunctionExpression(node, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.name !== name
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionExpression = updateFunctionExpression;
    function createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        var node = createSynthesizedNode(187 /* ArrowFunction */);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(36 /* EqualsGreaterThanToken */);
        node.body = ts.parenthesizeConciseBody(body);
        return node;
    }
    ts.createArrowFunction = createArrowFunction;
    function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) {
        var equalsGreaterThanToken;
        var body;
        if (bodyOrUndefined === undefined) {
            equalsGreaterThanToken = node.equalsGreaterThanToken;
            body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody);
        }
        else {
            equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) {
                return n.kind === 36 /* EqualsGreaterThanToken */;
            });
            body = bodyOrUndefined;
        }
        return node.modifiers !== modifiers
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.equalsGreaterThanToken !== equalsGreaterThanToken
            || node.body !== body
            ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
            : node;
    }
    ts.updateArrowFunction = updateArrowFunction;
    function createDelete(expression) {
        var node = createSynthesizedNode(188 /* DeleteExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createDelete = createDelete;
    function updateDelete(node, expression) {
        return node.expression !== expression
            ? updateNode(createDelete(expression), node)
            : node;
    }
    ts.updateDelete = updateDelete;
    function createTypeOf(expression) {
        var node = createSynthesizedNode(189 /* TypeOfExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeOf = createTypeOf;
    function updateTypeOf(node, expression) {
        return node.expression !== expression
            ? updateNode(createTypeOf(expression), node)
            : node;
    }
    ts.updateTypeOf = updateTypeOf;
    function createVoid(expression) {
        var node = createSynthesizedNode(190 /* VoidExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createVoid = createVoid;
    function updateVoid(node, expression) {
        return node.expression !== expression
            ? updateNode(createVoid(expression), node)
            : node;
    }
    ts.updateVoid = updateVoid;
    function createAwait(expression) {
        var node = createSynthesizedNode(191 /* AwaitExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createAwait = createAwait;
    function updateAwait(node, expression) {
        return node.expression !== expression
            ? updateNode(createAwait(expression), node)
            : node;
    }
    ts.updateAwait = updateAwait;
    function createPrefix(operator, operand) {
        var node = createSynthesizedNode(192 /* PrefixUnaryExpression */);
        node.operator = operator;
        node.operand = ts.parenthesizePrefixOperand(operand);
        return node;
    }
    ts.createPrefix = createPrefix;
    function updatePrefix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPrefix(node.operator, operand), node)
            : node;
    }
    ts.updatePrefix = updatePrefix;
    function createPostfix(operand, operator) {
        var node = createSynthesizedNode(193 /* PostfixUnaryExpression */);
        node.operand = ts.parenthesizePostfixOperand(operand);
        node.operator = operator;
        return node;
    }
    ts.createPostfix = createPostfix;
    function updatePostfix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPostfix(operand, node.operator), node)
            : node;
    }
    ts.updatePostfix = updatePostfix;
    function createBinary(left, operator, right) {
        var node = createSynthesizedNode(194 /* BinaryExpression */);
        var operatorToken = asToken(operator);
        var operatorKind = operatorToken.kind;
        node.left = ts.parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
        node.operatorToken = operatorToken;
        node.right = ts.parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left);
        return node;
    }
    ts.createBinary = createBinary;
    function updateBinary(node, left, right, operator) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createBinary(left, operator || node.operatorToken, right), node)
            : node;
    }
    ts.updateBinary = updateBinary;
    function createConditional(condition, questionTokenOrWhenTrue, whenTrueOrWhenFalse, colonToken, whenFalse) {
        var node = createSynthesizedNode(195 /* ConditionalExpression */);
        node.condition = ts.parenthesizeForConditionalHead(condition);
        node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(55 /* QuestionToken */);
        node.whenTrue = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue);
        node.colonToken = whenFalse ? colonToken : createToken(56 /* ColonToken */);
        node.whenFalse = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse);
        return node;
    }
    ts.createConditional = createConditional;
    function updateConditional(node, condition) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        if (args.length === 2) {
            var whenTrue_1 = args[0], whenFalse_1 = args[1];
            return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1);
        }
        ts.Debug.assert(args.length === 4);
        var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3];
        return node.condition !== condition
            || node.questionToken !== questionToken
            || node.whenTrue !== whenTrue
            || node.colonToken !== colonToken
            || node.whenFalse !== whenFalse
            ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
            : node;
    }
    ts.updateConditional = updateConditional;
    function createTemplateExpression(head, templateSpans) {
        var node = createSynthesizedNode(196 /* TemplateExpression */);
        node.head = head;
        node.templateSpans = createNodeArray(templateSpans);
        return node;
    }
    ts.createTemplateExpression = createTemplateExpression;
    function updateTemplateExpression(node, head, templateSpans) {
        return node.head !== head
            || node.templateSpans !== templateSpans
            ? updateNode(createTemplateExpression(head, templateSpans), node)
            : node;
    }
    ts.updateTemplateExpression = updateTemplateExpression;
    function createTemplateHead(text) {
        var node = createSynthesizedNode(14 /* TemplateHead */);
        node.text = text;
        return node;
    }
    ts.createTemplateHead = createTemplateHead;
    function createTemplateMiddle(text) {
        var node = createSynthesizedNode(15 /* TemplateMiddle */);
        node.text = text;
        return node;
    }
    ts.createTemplateMiddle = createTemplateMiddle;
    function createTemplateTail(text) {
        var node = createSynthesizedNode(16 /* TemplateTail */);
        node.text = text;
        return node;
    }
    ts.createTemplateTail = createTemplateTail;
    function createNoSubstitutionTemplateLiteral(text) {
        var node = createSynthesizedNode(13 /* NoSubstitutionTemplateLiteral */);
        node.text = text;
        return node;
    }
    ts.createNoSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral;
    function createYield(asteriskTokenOrExpression, expression) {
        var node = createSynthesizedNode(197 /* YieldExpression */);
        node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === 39 /* AsteriskToken */ ? asteriskTokenOrExpression : undefined;
        node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== 39 /* AsteriskToken */ ? asteriskTokenOrExpression : expression;
        return node;
    }
    ts.createYield = createYield;
    function updateYield(node, asteriskToken, expression) {
        return node.expression !== expression
            || node.asteriskToken !== asteriskToken
            ? updateNode(createYield(asteriskToken, expression), node)
            : node;
    }
    ts.updateYield = updateYield;
    function createSpread(expression) {
        var node = createSynthesizedNode(198 /* SpreadElement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpread = createSpread;
    function updateSpread(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpread(expression), node)
            : node;
    }
    ts.updateSpread = updateSpread;
    function createClassExpression(modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(199 /* ClassExpression */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassExpression = createClassExpression;
    function updateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassExpression = updateClassExpression;
    function createOmittedExpression() {
        return createSynthesizedNode(200 /* OmittedExpression */);
    }
    ts.createOmittedExpression = createOmittedExpression;
    function createExpressionWithTypeArguments(typeArguments, expression) {
        var node = createSynthesizedNode(201 /* ExpressionWithTypeArguments */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createExpressionWithTypeArguments = createExpressionWithTypeArguments;
    function updateExpressionWithTypeArguments(node, typeArguments, expression) {
        return node.typeArguments !== typeArguments
            || node.expression !== expression
            ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node)
            : node;
    }
    ts.updateExpressionWithTypeArguments = updateExpressionWithTypeArguments;
    function createAsExpression(expression, type) {
        var node = createSynthesizedNode(202 /* AsExpression */);
        node.expression = expression;
        node.type = type;
        return node;
    }
    ts.createAsExpression = createAsExpression;
    function updateAsExpression(node, expression, type) {
        return node.expression !== expression
            || node.type !== type
            ? updateNode(createAsExpression(expression, type), node)
            : node;
    }
    ts.updateAsExpression = updateAsExpression;
    function createNonNullExpression(expression) {
        var node = createSynthesizedNode(203 /* NonNullExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createNonNullExpression = createNonNullExpression;
    function updateNonNullExpression(node, expression) {
        return node.expression !== expression
            ? updateNode(createNonNullExpression(expression), node)
            : node;
    }
    ts.updateNonNullExpression = updateNonNullExpression;
    function createMetaProperty(keywordToken, name) {
        var node = createSynthesizedNode(204 /* MetaProperty */);
        node.keywordToken = keywordToken;
        node.name = name;
        return node;
    }
    ts.createMetaProperty = createMetaProperty;
    function updateMetaProperty(node, name) {
        return node.name !== name
            ? updateNode(createMetaProperty(node.keywordToken, name), node)
            : node;
    }
    ts.updateMetaProperty = updateMetaProperty;
    // Misc
    function createTemplateSpan(expression, literal) {
        var node = createSynthesizedNode(205 /* TemplateSpan */);
        node.expression = expression;
        node.literal = literal;
        return node;
    }
    ts.createTemplateSpan = createTemplateSpan;
    function updateTemplateSpan(node, expression, literal) {
        return node.expression !== expression
            || node.literal !== literal
            ? updateNode(createTemplateSpan(expression, literal), node)
            : node;
    }
    ts.updateTemplateSpan = updateTemplateSpan;
    function createSemicolonClassElement() {
        return createSynthesizedNode(206 /* SemicolonClassElement */);
    }
    ts.createSemicolonClassElement = createSemicolonClassElement;
    // Element
    function createBlock(statements, multiLine) {
        var block = createSynthesizedNode(207 /* Block */);
        block.statements = createNodeArray(statements);
        if (multiLine)
            block.multiLine = multiLine;
        return block;
    }
    ts.createBlock = createBlock;
    function updateBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createBlock(statements, node.multiLine), node)
            : node;
    }
    ts.updateBlock = updateBlock;
    function createVariableStatement(modifiers, declarationList) {
        var node = createSynthesizedNode(208 /* VariableStatement */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
        return node;
    }
    ts.createVariableStatement = createVariableStatement;
    function updateVariableStatement(node, modifiers, declarationList) {
        return node.modifiers !== modifiers
            || node.declarationList !== declarationList
            ? updateNode(createVariableStatement(modifiers, declarationList), node)
            : node;
    }
    ts.updateVariableStatement = updateVariableStatement;
    function createEmptyStatement() {
        return createSynthesizedNode(209 /* EmptyStatement */);
    }
    ts.createEmptyStatement = createEmptyStatement;
    function createStatement(expression) {
        var node = createSynthesizedNode(210 /* ExpressionStatement */);
        node.expression = ts.parenthesizeExpressionForExpressionStatement(expression);
        return node;
    }
    ts.createStatement = createStatement;
    function updateStatement(node, expression) {
        return node.expression !== expression
            ? updateNode(createStatement(expression), node)
            : node;
    }
    ts.updateStatement = updateStatement;
    function createIf(expression, thenStatement, elseStatement) {
        var node = createSynthesizedNode(211 /* IfStatement */);
        node.expression = expression;
        node.thenStatement = thenStatement;
        node.elseStatement = elseStatement;
        return node;
    }
    ts.createIf = createIf;
    function updateIf(node, expression, thenStatement, elseStatement) {
        return node.expression !== expression
            || node.thenStatement !== thenStatement
            || node.elseStatement !== elseStatement
            ? updateNode(createIf(expression, thenStatement, elseStatement), node)
            : node;
    }
    ts.updateIf = updateIf;
    function createDo(statement, expression) {
        var node = createSynthesizedNode(212 /* DoStatement */);
        node.statement = statement;
        node.expression = expression;
        return node;
    }
    ts.createDo = createDo;
    function updateDo(node, statement, expression) {
        return node.statement !== statement
            || node.expression !== expression
            ? updateNode(createDo(statement, expression), node)
            : node;
    }
    ts.updateDo = updateDo;
    function createWhile(expression, statement) {
        var node = createSynthesizedNode(213 /* WhileStatement */);
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createWhile = createWhile;
    function updateWhile(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWhile(expression, statement), node)
            : node;
    }
    ts.updateWhile = updateWhile;
    function createFor(initializer, condition, incrementor, statement) {
        var node = createSynthesizedNode(214 /* ForStatement */);
        node.initializer = initializer;
        node.condition = condition;
        node.incrementor = incrementor;
        node.statement = statement;
        return node;
    }
    ts.createFor = createFor;
    function updateFor(node, initializer, condition, incrementor, statement) {
        return node.initializer !== initializer
            || node.condition !== condition
            || node.incrementor !== incrementor
            || node.statement !== statement
            ? updateNode(createFor(initializer, condition, incrementor, statement), node)
            : node;
    }
    ts.updateFor = updateFor;
    function createForIn(initializer, expression, statement) {
        var node = createSynthesizedNode(215 /* ForInStatement */);
        node.initializer = initializer;
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createForIn = createForIn;
    function updateForIn(node, initializer, expression, statement) {
        return node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForIn(initializer, expression, statement), node)
            : node;
    }
    ts.updateForIn = updateForIn;
    function createForOf(awaitModifier, initializer, expression, statement) {
        var node = createSynthesizedNode(216 /* ForOfStatement */);
        node.awaitModifier = awaitModifier;
        node.initializer = initializer;
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createForOf = createForOf;
    function updateForOf(node, awaitModifier, initializer, expression, statement) {
        return node.awaitModifier !== awaitModifier
            || node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node)
            : node;
    }
    ts.updateForOf = updateForOf;
    function createContinue(label) {
        var node = createSynthesizedNode(217 /* ContinueStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createContinue = createContinue;
    function updateContinue(node, label) {
        return node.label !== label
            ? updateNode(createContinue(label), node)
            : node;
    }
    ts.updateContinue = updateContinue;
    function createBreak(label) {
        var node = createSynthesizedNode(218 /* BreakStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createBreak = createBreak;
    function updateBreak(node, label) {
        return node.label !== label
            ? updateNode(createBreak(label), node)
            : node;
    }
    ts.updateBreak = updateBreak;
    function createReturn(expression) {
        var node = createSynthesizedNode(219 /* ReturnStatement */);
        node.expression = expression;
        return node;
    }
    ts.createReturn = createReturn;
    function updateReturn(node, expression) {
        return node.expression !== expression
            ? updateNode(createReturn(expression), node)
            : node;
    }
    ts.updateReturn = updateReturn;
    function createWith(expression, statement) {
        var node = createSynthesizedNode(220 /* WithStatement */);
        node.expression = expression;
        node.statement = statement;
        return node;
    }
    ts.createWith = createWith;
    function updateWith(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWith(expression, statement), node)
            : node;
    }
    ts.updateWith = updateWith;
    function createSwitch(expression, caseBlock) {
        var node = createSynthesizedNode(221 /* SwitchStatement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.caseBlock = caseBlock;
        return node;
    }
    ts.createSwitch = createSwitch;
    function updateSwitch(node, expression, caseBlock) {
        return node.expression !== expression
            || node.caseBlock !== caseBlock
            ? updateNode(createSwitch(expression, caseBlock), node)
            : node;
    }
    ts.updateSwitch = updateSwitch;
    function createLabel(label, statement) {
        var node = createSynthesizedNode(222 /* LabeledStatement */);
        node.label = asName(label);
        node.statement = statement;
        return node;
    }
    ts.createLabel = createLabel;
    function updateLabel(node, label, statement) {
        return node.label !== label
            || node.statement !== statement
            ? updateNode(createLabel(label, statement), node)
            : node;
    }
    ts.updateLabel = updateLabel;
    function createThrow(expression) {
        var node = createSynthesizedNode(223 /* ThrowStatement */);
        node.expression = expression;
        return node;
    }
    ts.createThrow = createThrow;
    function updateThrow(node, expression) {
        return node.expression !== expression
            ? updateNode(createThrow(expression), node)
            : node;
    }
    ts.updateThrow = updateThrow;
    function createTry(tryBlock, catchClause, finallyBlock) {
        var node = createSynthesizedNode(224 /* TryStatement */);
        node.tryBlock = tryBlock;
        node.catchClause = catchClause;
        node.finallyBlock = finallyBlock;
        return node;
    }
    ts.createTry = createTry;
    function updateTry(node, tryBlock, catchClause, finallyBlock) {
        return node.tryBlock !== tryBlock
            || node.catchClause !== catchClause
            || node.finallyBlock !== finallyBlock
            ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node)
            : node;
    }
    ts.updateTry = updateTry;
    function createDebuggerStatement() {
        return createSynthesizedNode(225 /* DebuggerStatement */);
    }
    ts.createDebuggerStatement = createDebuggerStatement;
    function createVariableDeclaration(name, type, initializer) {
        var node = createSynthesizedNode(226 /* VariableDeclaration */);
        node.name = asName(name);
        node.type = type;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createVariableDeclaration = createVariableDeclaration;
    function updateVariableDeclaration(node, name, type, initializer) {
        return node.name !== name
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createVariableDeclaration(name, type, initializer), node)
            : node;
    }
    ts.updateVariableDeclaration = updateVariableDeclaration;
    function createVariableDeclarationList(declarations, flags) {
        var node = createSynthesizedNode(227 /* VariableDeclarationList */);
        node.flags |= flags & 3 /* BlockScoped */;
        node.declarations = createNodeArray(declarations);
        return node;
    }
    ts.createVariableDeclarationList = createVariableDeclarationList;
    function updateVariableDeclarationList(node, declarations) {
        return node.declarations !== declarations
            ? updateNode(createVariableDeclarationList(declarations, node.flags), node)
            : node;
    }
    ts.updateVariableDeclarationList = updateVariableDeclarationList;
    function createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(228 /* FunctionDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionDeclaration = createFunctionDeclaration;
    function updateFunctionDeclaration(node, decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionDeclaration = updateFunctionDeclaration;
    function createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(229 /* ClassDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassDeclaration = createClassDeclaration;
    function updateClassDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassDeclaration = updateClassDeclaration;
    function createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(230 /* InterfaceDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createInterfaceDeclaration = createInterfaceDeclaration;
    function updateInterfaceDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateInterfaceDeclaration = updateInterfaceDeclaration;
    function createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type) {
        var node = createSynthesizedNode(231 /* TypeAliasDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.type = type;
        return node;
    }
    ts.createTypeAliasDeclaration = createTypeAliasDeclaration;
    function updateTypeAliasDeclaration(node, decorators, modifiers, name, typeParameters, type) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.type !== type
            ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node)
            : node;
    }
    ts.updateTypeAliasDeclaration = updateTypeAliasDeclaration;
    function createEnumDeclaration(decorators, modifiers, name, members) {
        var node = createSynthesizedNode(232 /* EnumDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createEnumDeclaration = createEnumDeclaration;
    function updateEnumDeclaration(node, decorators, modifiers, name, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.members !== members
            ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node)
            : node;
    }
    ts.updateEnumDeclaration = updateEnumDeclaration;
    function createModuleDeclaration(decorators, modifiers, name, body, flags) {
        var node = createSynthesizedNode(233 /* ModuleDeclaration */);
        node.flags |= flags & (16 /* Namespace */ | 4 /* NestedNamespace */ | 512 /* GlobalAugmentation */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = name;
        node.body = body;
        return node;
    }
    ts.createModuleDeclaration = createModuleDeclaration;
    function updateModuleDeclaration(node, decorators, modifiers, name, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.body !== body
            ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node)
            : node;
    }
    ts.updateModuleDeclaration = updateModuleDeclaration;
    function createModuleBlock(statements) {
        var node = createSynthesizedNode(234 /* ModuleBlock */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createModuleBlock = createModuleBlock;
    function updateModuleBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createModuleBlock(statements), node)
            : node;
    }
    ts.updateModuleBlock = updateModuleBlock;
    function createCaseBlock(clauses) {
        var node = createSynthesizedNode(235 /* CaseBlock */);
        node.clauses = createNodeArray(clauses);
        return node;
    }
    ts.createCaseBlock = createCaseBlock;
    function updateCaseBlock(node, clauses) {
        return node.clauses !== clauses
            ? updateNode(createCaseBlock(clauses), node)
            : node;
    }
    ts.updateCaseBlock = updateCaseBlock;
    function createNamespaceExportDeclaration(name) {
        var node = createSynthesizedNode(236 /* NamespaceExportDeclaration */);
        node.name = asName(name);
        return node;
    }
    ts.createNamespaceExportDeclaration = createNamespaceExportDeclaration;
    function updateNamespaceExportDeclaration(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceExportDeclaration(name), node)
            : node;
    }
    ts.updateNamespaceExportDeclaration = updateNamespaceExportDeclaration;
    function createImportEqualsDeclaration(decorators, modifiers, name, moduleReference) {
        var node = createSynthesizedNode(237 /* ImportEqualsDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.moduleReference = moduleReference;
        return node;
    }
    ts.createImportEqualsDeclaration = createImportEqualsDeclaration;
    function updateImportEqualsDeclaration(node, decorators, modifiers, name, moduleReference) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.moduleReference !== moduleReference
            ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node)
            : node;
    }
    ts.updateImportEqualsDeclaration = updateImportEqualsDeclaration;
    function createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier) {
        var node = createSynthesizedNode(238 /* ImportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.importClause = importClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createImportDeclaration = createImportDeclaration;
    function updateImportDeclaration(node, decorators, modifiers, importClause, moduleSpecifier) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.importClause !== importClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node)
            : node;
    }
    ts.updateImportDeclaration = updateImportDeclaration;
    function createImportClause(name, namedBindings) {
        var node = createSynthesizedNode(239 /* ImportClause */);
        node.name = name;
        node.namedBindings = namedBindings;
        return node;
    }
    ts.createImportClause = createImportClause;
    function updateImportClause(node, name, namedBindings) {
        return node.name !== name
            || node.namedBindings !== namedBindings
            ? updateNode(createImportClause(name, namedBindings), node)
            : node;
    }
    ts.updateImportClause = updateImportClause;
    function createNamespaceImport(name) {
        var node = createSynthesizedNode(240 /* NamespaceImport */);
        node.name = name;
        return node;
    }
    ts.createNamespaceImport = createNamespaceImport;
    function updateNamespaceImport(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceImport(name), node)
            : node;
    }
    ts.updateNamespaceImport = updateNamespaceImport;
    function createNamedImports(elements) {
        var node = createSynthesizedNode(241 /* NamedImports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedImports = createNamedImports;
    function updateNamedImports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedImports(elements), node)
            : node;
    }
    ts.updateNamedImports = updateNamedImports;
    function createImportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(242 /* ImportSpecifier */);
        node.propertyName = propertyName;
        node.name = name;
        return node;
    }
    ts.createImportSpecifier = createImportSpecifier;
    function updateImportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createImportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateImportSpecifier = updateImportSpecifier;
    function createExportAssignment(decorators, modifiers, isExportEquals, expression) {
        var node = createSynthesizedNode(243 /* ExportAssignment */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.isExportEquals = isExportEquals;
        node.expression = expression;
        return node;
    }
    ts.createExportAssignment = createExportAssignment;
    function updateExportAssignment(node, decorators, modifiers, expression) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.expression !== expression
            ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node)
            : node;
    }
    ts.updateExportAssignment = updateExportAssignment;
    function createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier) {
        var node = createSynthesizedNode(244 /* ExportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.exportClause = exportClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createExportDeclaration = createExportDeclaration;
    function updateExportDeclaration(node, decorators, modifiers, exportClause, moduleSpecifier) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.exportClause !== exportClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier), node)
            : node;
    }
    ts.updateExportDeclaration = updateExportDeclaration;
    function createNamedExports(elements) {
        var node = createSynthesizedNode(245 /* NamedExports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedExports = createNamedExports;
    function updateNamedExports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedExports(elements), node)
            : node;
    }
    ts.updateNamedExports = updateNamedExports;
    function createExportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(246 /* ExportSpecifier */);
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        return node;
    }
    ts.createExportSpecifier = createExportSpecifier;
    function updateExportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createExportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateExportSpecifier = updateExportSpecifier;
    // Module references
    function createExternalModuleReference(expression) {
        var node = createSynthesizedNode(248 /* ExternalModuleReference */);
        node.expression = expression;
        return node;
    }
    ts.createExternalModuleReference = createExternalModuleReference;
    function updateExternalModuleReference(node, expression) {
        return node.expression !== expression
            ? updateNode(createExternalModuleReference(expression), node)
            : node;
    }
    ts.updateExternalModuleReference = updateExternalModuleReference;
    // JSX
    function createJsxElement(openingElement, children, closingElement) {
        var node = createSynthesizedNode(249 /* JsxElement */);
        node.openingElement = openingElement;
        node.children = createNodeArray(children);
        node.closingElement = closingElement;
        return node;
    }
    ts.createJsxElement = createJsxElement;
    function updateJsxElement(node, openingElement, children, closingElement) {
        return node.openingElement !== openingElement
            || node.children !== children
            || node.closingElement !== closingElement
            ? updateNode(createJsxElement(openingElement, children, closingElement), node)
            : node;
    }
    ts.updateJsxElement = updateJsxElement;
    function createJsxSelfClosingElement(tagName, attributes) {
        var node = createSynthesizedNode(250 /* JsxSelfClosingElement */);
        node.tagName = tagName;
        node.attributes = attributes;
        return node;
    }
    ts.createJsxSelfClosingElement = createJsxSelfClosingElement;
    function updateJsxSelfClosingElement(node, tagName, attributes) {
        return node.tagName !== tagName
            || node.attributes !== attributes
            ? updateNode(createJsxSelfClosingElement(tagName, attributes), node)
            : node;
    }
    ts.updateJsxSelfClosingElement = updateJsxSelfClosingElement;
    function createJsxOpeningElement(tagName, attributes) {
        var node = createSynthesizedNode(251 /* JsxOpeningElement */);
        node.tagName = tagName;
        node.attributes = attributes;
        return node;
    }
    ts.createJsxOpeningElement = createJsxOpeningElement;
    function updateJsxOpeningElement(node, tagName, attributes) {
        return node.tagName !== tagName
            || node.attributes !== attributes
            ? updateNode(createJsxOpeningElement(tagName, attributes), node)
            : node;
    }
    ts.updateJsxOpeningElement = updateJsxOpeningElement;
    function createJsxClosingElement(tagName) {
        var node = createSynthesizedNode(252 /* JsxClosingElement */);
        node.tagName = tagName;
        return node;
    }
    ts.createJsxClosingElement = createJsxClosingElement;
    function updateJsxClosingElement(node, tagName) {
        return node.tagName !== tagName
            ? updateNode(createJsxClosingElement(tagName), node)
            : node;
    }
    ts.updateJsxClosingElement = updateJsxClosingElement;
    function createJsxAttribute(name, initializer) {
        var node = createSynthesizedNode(253 /* JsxAttribute */);
        node.name = name;
        node.initializer = initializer;
        return node;
    }
    ts.createJsxAttribute = createJsxAttribute;
    function updateJsxAttribute(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createJsxAttribute(name, initializer), node)
            : node;
    }
    ts.updateJsxAttribute = updateJsxAttribute;
    function createJsxAttributes(properties) {
        var node = createSynthesizedNode(254 /* JsxAttributes */);
        node.properties = createNodeArray(properties);
        return node;
    }
    ts.createJsxAttributes = createJsxAttributes;
    function updateJsxAttributes(node, properties) {
        return node.properties !== properties
            ? updateNode(createJsxAttributes(properties), node)
            : node;
    }
    ts.updateJsxAttributes = updateJsxAttributes;
    function createJsxSpreadAttribute(expression) {
        var node = createSynthesizedNode(255 /* JsxSpreadAttribute */);
        node.expression = expression;
        return node;
    }
    ts.createJsxSpreadAttribute = createJsxSpreadAttribute;
    function updateJsxSpreadAttribute(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxSpreadAttribute(expression), node)
            : node;
    }
    ts.updateJsxSpreadAttribute = updateJsxSpreadAttribute;
    function createJsxExpression(dotDotDotToken, expression) {
        var node = createSynthesizedNode(256 /* JsxExpression */);
        node.dotDotDotToken = dotDotDotToken;
        node.expression = expression;
        return node;
    }
    ts.createJsxExpression = createJsxExpression;
    function updateJsxExpression(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
            : node;
    }
    ts.updateJsxExpression = updateJsxExpression;
    // Clauses
    function createCaseClause(expression, statements) {
        var node = createSynthesizedNode(257 /* CaseClause */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createCaseClause = createCaseClause;
    function updateCaseClause(node, expression, statements) {
        return node.expression !== expression
            || node.statements !== statements
            ? updateNode(createCaseClause(expression, statements), node)
            : node;
    }
    ts.updateCaseClause = updateCaseClause;
    function createDefaultClause(statements) {
        var node = createSynthesizedNode(258 /* DefaultClause */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createDefaultClause = createDefaultClause;
    function updateDefaultClause(node, statements) {
        return node.statements !== statements
            ? updateNode(createDefaultClause(statements), node)
            : node;
    }
    ts.updateDefaultClause = updateDefaultClause;
    function createHeritageClause(token, types) {
        var node = createSynthesizedNode(259 /* HeritageClause */);
        node.token = token;
        node.types = createNodeArray(types);
        return node;
    }
    ts.createHeritageClause = createHeritageClause;
    function updateHeritageClause(node, types) {
        return node.types !== types
            ? updateNode(createHeritageClause(node.token, types), node)
            : node;
    }
    ts.updateHeritageClause = updateHeritageClause;
    function createCatchClause(variableDeclaration, block) {
        var node = createSynthesizedNode(260 /* CatchClause */);
        node.variableDeclaration = ts.isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
        node.block = block;
        return node;
    }
    ts.createCatchClause = createCatchClause;
    function updateCatchClause(node, variableDeclaration, block) {
        return node.variableDeclaration !== variableDeclaration
            || node.block !== block
            ? updateNode(createCatchClause(variableDeclaration, block), node)
            : node;
    }
    ts.updateCatchClause = updateCatchClause;
    // Property assignments
    function createPropertyAssignment(name, initializer) {
        var node = createSynthesizedNode(261 /* PropertyAssignment */);
        node.name = asName(name);
        node.questionToken = undefined;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createPropertyAssignment = createPropertyAssignment;
    function updatePropertyAssignment(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createPropertyAssignment(name, initializer), node)
            : node;
    }
    ts.updatePropertyAssignment = updatePropertyAssignment;
    function createShorthandPropertyAssignment(name, objectAssignmentInitializer) {
        var node = createSynthesizedNode(262 /* ShorthandPropertyAssignment */);
        node.name = asName(name);
        node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? ts.parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
        return node;
    }
    ts.createShorthandPropertyAssignment = createShorthandPropertyAssignment;
    function updateShorthandPropertyAssignment(node, name, objectAssignmentInitializer) {
        return node.name !== name
            || node.objectAssignmentInitializer !== objectAssignmentInitializer
            ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node)
            : node;
    }
    ts.updateShorthandPropertyAssignment = updateShorthandPropertyAssignment;
    function createSpreadAssignment(expression) {
        var node = createSynthesizedNode(263 /* SpreadAssignment */);
        node.expression = expression !== undefined ? ts.parenthesizeExpressionForList(expression) : undefined;
        return node;
    }
    ts.createSpreadAssignment = createSpreadAssignment;
    function updateSpreadAssignment(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpreadAssignment(expression), node)
            : node;
    }
    ts.updateSpreadAssignment = updateSpreadAssignment;
    // Enum
    function createEnumMember(name, initializer) {
        var node = createSynthesizedNode(264 /* EnumMember */);
        node.name = asName(name);
        node.initializer = initializer && ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createEnumMember = createEnumMember;
    function updateEnumMember(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createEnumMember(name, initializer), node)
            : node;
    }
    ts.updateEnumMember = updateEnumMember;
    // Top-level nodes
    function updateSourceFileNode(node, statements) {
        if (node.statements !== statements) {
            var updated = createSynthesizedNode(265 /* SourceFile */);
            updated.flags |= node.flags;
            updated.statements = createNodeArray(statements);
            updated.endOfFileToken = node.endOfFileToken;
            updated.fileName = node.fileName;
            updated.path = node.path;
            updated.text = node.text;
            if (node.amdDependencies !== undefined)
                updated.amdDependencies = node.amdDependencies;
            if (node.moduleName !== undefined)
                updated.moduleName = node.moduleName;
            if (node.referencedFiles !== undefined)
                updated.referencedFiles = node.referencedFiles;
            if (node.typeReferenceDirectives !== undefined)
                updated.typeReferenceDirectives = node.typeReferenceDirectives;
            if (node.languageVariant !== undefined)
                updated.languageVariant = node.languageVariant;
            if (node.isDeclarationFile !== undefined)
                updated.isDeclarationFile = node.isDeclarationFile;
            if (node.renamedDependencies !== undefined)
                updated.renamedDependencies = node.renamedDependencies;
            if (node.hasNoDefaultLib !== undefined)
                updated.hasNoDefaultLib = node.hasNoDefaultLib;
            if (node.languageVersion !== undefined)
                updated.languageVersion = node.languageVersion;
            if (node.scriptKind !== undefined)
                updated.scriptKind = node.scriptKind;
            if (node.externalModuleIndicator !== undefined)
                updated.externalModuleIndicator = node.externalModuleIndicator;
            if (node.commonJsModuleIndicator !== undefined)
                updated.commonJsModuleIndicator = node.commonJsModuleIndicator;
            if (node.identifiers !== undefined)
                updated.identifiers = node.identifiers;
            if (node.nodeCount !== undefined)
                updated.nodeCount = node.nodeCount;
            if (node.identifierCount !== undefined)
                updated.identifierCount = node.identifierCount;
            if (node.symbolCount !== undefined)
                updated.symbolCount = node.symbolCount;
            if (node.parseDiagnostics !== undefined)
                updated.parseDiagnostics = node.parseDiagnostics;
            if (node.bindDiagnostics !== undefined)
                updated.bindDiagnostics = node.bindDiagnostics;
            if (node.lineMap !== undefined)
                updated.lineMap = node.lineMap;
            if (node.classifiableNames !== undefined)
                updated.classifiableNames = node.classifiableNames;
            if (node.resolvedModules !== undefined)
                updated.resolvedModules = node.resolvedModules;
            if (node.resolvedTypeReferenceDirectiveNames !== undefined)
                updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
            if (node.imports !== undefined)
                updated.imports = node.imports;
            if (node.moduleAugmentations !== undefined)
                updated.moduleAugmentations = node.moduleAugmentations;
            return updateNode(updated, node);
        }
        return node;
    }
    ts.updateSourceFileNode = updateSourceFileNode;
    /**
     * Creates a shallow, memberwise clone of a node for mutation.
     */
    function getMutableClone(node) {
        var clone = getSynthesizedClone(node);
        clone.pos = node.pos;
        clone.end = node.end;
        clone.parent = node.parent;
        return clone;
    }
    ts.getMutableClone = getMutableClone;
    // Transformation nodes
    /**
     * Creates a synthetic statement to act as a placeholder for a not-emitted statement in
     * order to preserve comments.
     *
     * @param original The original statement.
     */
    function createNotEmittedStatement(original) {
        var node = createSynthesizedNode(287 /* NotEmittedStatement */);
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createNotEmittedStatement = createNotEmittedStatement;
    /**
     * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createEndOfDeclarationMarker(original) {
        var node = createSynthesizedNode(291 /* EndOfDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createEndOfDeclarationMarker = createEndOfDeclarationMarker;
    /**
     * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createMergeDeclarationMarker(original) {
        var node = createSynthesizedNode(290 /* MergeDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createMergeDeclarationMarker = createMergeDeclarationMarker;
    /**
     * Creates a synthetic expression to act as a placeholder for a not-emitted expression in
     * order to preserve comments or sourcemap positions.
     *
     * @param expression The inner expression to emit.
     * @param original The original outer expression.
     * @param location The location for the expression. Defaults to the positions from "original" if provided.
     */
    function createPartiallyEmittedExpression(expression, original) {
        var node = createSynthesizedNode(288 /* PartiallyEmittedExpression */);
        node.expression = expression;
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createPartiallyEmittedExpression = createPartiallyEmittedExpression;
    function updatePartiallyEmittedExpression(node, expression) {
        if (node.expression !== expression) {
            return updateNode(createPartiallyEmittedExpression(expression, node.original), node);
        }
        return node;
    }
    ts.updatePartiallyEmittedExpression = updatePartiallyEmittedExpression;
    function flattenCommaElements(node) {
        if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
            if (node.kind === 289 /* CommaListExpression */) {
                return node.elements;
            }
            if (ts.isBinaryExpression(node) && node.operatorToken.kind === 26 /* CommaToken */) {
                return [node.left, node.right];
            }
        }
        return node;
    }
    function createCommaList(elements) {
        var node = createSynthesizedNode(289 /* CommaListExpression */);
        node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements));
        return node;
    }
    ts.createCommaList = createCommaList;
    function updateCommaList(node, elements) {
        return node.elements !== elements
            ? updateNode(createCommaList(elements), node)
            : node;
    }
    ts.updateCommaList = updateCommaList;
    function createBundle(sourceFiles) {
        var node = ts.createNode(266 /* Bundle */);
        node.sourceFiles = sourceFiles;
        return node;
    }
    ts.createBundle = createBundle;
    function updateBundle(node, sourceFiles) {
        if (node.sourceFiles !== sourceFiles) {
            return createBundle(sourceFiles);
        }
        return node;
    }
    ts.updateBundle = updateBundle;
    function createImmediatelyInvokedFunctionExpression(statements, param, paramValue) {
        return createCall(createFunctionExpression(
        /*modifiers*/ undefined, 
        /*asteriskToken*/ undefined, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
        return createCall(createArrowFunction(
        /*modifiers*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, 
        /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
    function createComma(left, right) {
        return createBinary(left, 26 /* CommaToken */, right);
    }
    ts.createComma = createComma;
    function createLessThan(left, right) {
        return createBinary(left, 27 /* LessThanToken */, right);
    }
    ts.createLessThan = createLessThan;
    function createAssignment(left, right) {
        return createBinary(left, 58 /* EqualsToken */, right);
    }
    ts.createAssignment = createAssignment;
    function createStrictEquality(left, right) {
        return createBinary(left, 34 /* EqualsEqualsEqualsToken */, right);
    }
    ts.createStrictEquality = createStrictEquality;
    function createStrictInequality(left, right) {
        return createBinary(left, 35 /* ExclamationEqualsEqualsToken */, right);
    }
    ts.createStrictInequality = createStrictInequality;
    function createAdd(left, right) {
        return createBinary(left, 37 /* PlusToken */, right);
    }
    ts.createAdd = createAdd;
    function createSubtract(left, right) {
        return createBinary(left, 38 /* MinusToken */, right);
    }
    ts.createSubtract = createSubtract;
    function createPostfixIncrement(operand) {
        return createPostfix(operand, 43 /* PlusPlusToken */);
    }
    ts.createPostfixIncrement = createPostfixIncrement;
    function createLogicalAnd(left, right) {
        return createBinary(left, 53 /* AmpersandAmpersandToken */, right);
    }
    ts.createLogicalAnd = createLogicalAnd;
    function createLogicalOr(left, right) {
        return createBinary(left, 54 /* BarBarToken */, right);
    }
    ts.createLogicalOr = createLogicalOr;
    function createLogicalNot(operand) {
        return createPrefix(51 /* ExclamationToken */, operand);
    }
    ts.createLogicalNot = createLogicalNot;
    function createVoidZero() {
        return createVoid(createLiteral(0));
    }
    ts.createVoidZero = createVoidZero;
    function createExportDefault(expression) {
        return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
    }
    ts.createExportDefault = createExportDefault;
    function createExternalModuleExport(exportName) {
        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
    }
    ts.createExternalModuleExport = createExternalModuleExport;
    function asName(name) {
        return ts.isString(name) ? createIdentifier(name) : name;
    }
    function asExpression(value) {
        return ts.isString(value) || typeof value === "number" ? createLiteral(value) : value;
    }
    function asNodeArray(array) {
        return array ? createNodeArray(array) : undefined;
    }
    function asToken(value) {
        return typeof value === "number" ? createToken(value) : value;
    }
    /**
     * Clears any EmitNode entries from parse-tree nodes.
     * @param sourceFile A source file.
     */
    function disposeEmitNodes(sourceFile) {
        // During transformation we may need to annotate a parse tree node with transient
        // transformation properties. As parse tree nodes live longer than transformation
        // nodes, we need to make sure we reclaim any memory allocated for custom ranges
        // from these nodes to ensure we do not hold onto entire subtrees just for position
        // information. We also need to reset these nodes to a pre-transformation state
        // for incremental parsing scenarios so that we do not impact later emit.
        sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile));
        var emitNode = sourceFile && sourceFile.emitNode;
        var annotatedNodes = emitNode && emitNode.annotatedNodes;
        if (annotatedNodes) {
            for (var _i = 0, annotatedNodes_1 = annotatedNodes; _i < annotatedNodes_1.length; _i++) {
                var node = annotatedNodes_1[_i];
                node.emitNode = undefined;
            }
        }
    }
    ts.disposeEmitNodes = disposeEmitNodes;
    /**
     * Associates a node with the current transformation, initializing
     * various transient transformation properties.
     */
    /* @internal */
    function getOrCreateEmitNode(node) {
        if (!node.emitNode) {
            if (ts.isParseTreeNode(node)) {
                // To avoid holding onto transformation artifacts, we keep track of any
                // parse tree node we are annotating. This allows us to clean them up after
                // all transformations have completed.
                if (node.kind === 265 /* SourceFile */) {
                    return node.emitNode = { annotatedNodes: [node] };
                }
                var sourceFile = ts.getSourceFileOfNode(node);
                getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
            }
            node.emitNode = {};
        }
        return node.emitNode;
    }
    ts.getOrCreateEmitNode = getOrCreateEmitNode;
    function setTextRange(range, location) {
        if (location) {
            range.pos = location.pos;
            range.end = location.end;
        }
        return range;
    }
    ts.setTextRange = setTextRange;
    /**
     * Sets flags that control emit behavior of a node.
     */
    function setEmitFlags(node, emitFlags) {
        getOrCreateEmitNode(node).flags = emitFlags;
        return node;
    }
    ts.setEmitFlags = setEmitFlags;
    /**
     * Sets flags that control emit behavior of a node.
     */
    /* @internal */
    function addEmitFlags(node, emitFlags) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.flags = emitNode.flags | emitFlags;
        return node;
    }
    ts.addEmitFlags = addEmitFlags;
    /**
     * Gets a custom text range to use when emitting source maps.
     */
    function getSourceMapRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.sourceMapRange) || node;
    }
    ts.getSourceMapRange = getSourceMapRange;
    /**
     * Sets a custom text range to use when emitting source maps.
     */
    function setSourceMapRange(node, range) {
        getOrCreateEmitNode(node).sourceMapRange = range;
        return node;
    }
    ts.setSourceMapRange = setSourceMapRange;
    var SourceMapSource;
    /**
     * Create an external source map source file reference
     */
    function createSourceMapSource(fileName, text, skipTrivia) {
        return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia);
    }
    ts.createSourceMapSource = createSourceMapSource;
    /**
     * Gets the TextRange to use for source maps for a token of a node.
     */
    function getTokenSourceMapRange(node, token) {
        var emitNode = node.emitNode;
        var tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
        return tokenSourceMapRanges && tokenSourceMapRanges[token];
    }
    ts.getTokenSourceMapRange = getTokenSourceMapRange;
    /**
     * Sets the TextRange to use for source maps for a token of a node.
     */
    function setTokenSourceMapRange(node, token, range) {
        var emitNode = getOrCreateEmitNode(node);
        var tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
        tokenSourceMapRanges[token] = range;
        return node;
    }
    ts.setTokenSourceMapRange = setTokenSourceMapRange;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    function getCommentRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.commentRange) || node;
    }
    ts.getCommentRange = getCommentRange;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    function setCommentRange(node, range) {
        getOrCreateEmitNode(node).commentRange = range;
        return node;
    }
    ts.setCommentRange = setCommentRange;
    function getSyntheticLeadingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.leadingComments;
    }
    ts.getSyntheticLeadingComments = getSyntheticLeadingComments;
    function setSyntheticLeadingComments(node, comments) {
        getOrCreateEmitNode(node).leadingComments = comments;
        return node;
    }
    ts.setSyntheticLeadingComments = setSyntheticLeadingComments;
    function addSyntheticLeadingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticLeadingComment = addSyntheticLeadingComment;
    function getSyntheticTrailingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.trailingComments;
    }
    ts.getSyntheticTrailingComments = getSyntheticTrailingComments;
    function setSyntheticTrailingComments(node, comments) {
        getOrCreateEmitNode(node).trailingComments = comments;
        return node;
    }
    ts.setSyntheticTrailingComments = setSyntheticTrailingComments;
    function addSyntheticTrailingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticTrailingComment = addSyntheticTrailingComment;
    /**
     * Gets the constant value to emit for an expression.
     */
    function getConstantValue(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.constantValue;
    }
    ts.getConstantValue = getConstantValue;
    /**
     * Sets the constant value to emit for an expression.
     */
    function setConstantValue(node, value) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.constantValue = value;
        return node;
    }
    ts.setConstantValue = setConstantValue;
    /**
     * Adds an EmitHelper to a node.
     */
    function addEmitHelper(node, helper) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.helpers = ts.append(emitNode.helpers, helper);
        return node;
    }
    ts.addEmitHelper = addEmitHelper;
    /**
     * Add EmitHelpers to a node.
     */
    function addEmitHelpers(node, helpers) {
        if (ts.some(helpers)) {
            var emitNode = getOrCreateEmitNode(node);
            for (var _i = 0, helpers_1 = helpers; _i < helpers_1.length; _i++) {
                var helper = helpers_1[_i];
                emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper);
            }
        }
        return node;
    }
    ts.addEmitHelpers = addEmitHelpers;
    /**
     * Removes an EmitHelper from a node.
     */
    function removeEmitHelper(node, helper) {
        var emitNode = node.emitNode;
        if (emitNode) {
            var helpers = emitNode.helpers;
            if (helpers) {
                return ts.orderedRemoveItem(helpers, helper);
            }
        }
        return false;
    }
    ts.removeEmitHelper = removeEmitHelper;
    /**
     * Gets the EmitHelpers of a node.
     */
    function getEmitHelpers(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.helpers;
    }
    ts.getEmitHelpers = getEmitHelpers;
    /**
     * Moves matching emit helpers from a source node to a target node.
     */
    function moveEmitHelpers(source, target, predicate) {
        var sourceEmitNode = source.emitNode;
        var sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers;
        if (!ts.some(sourceEmitHelpers))
            return;
        var targetEmitNode = getOrCreateEmitNode(target);
        var helpersRemoved = 0;
        for (var i = 0; i < sourceEmitHelpers.length; i++) {
            var helper = sourceEmitHelpers[i];
            if (predicate(helper)) {
                helpersRemoved++;
                targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper);
            }
            else if (helpersRemoved > 0) {
                sourceEmitHelpers[i - helpersRemoved] = helper;
            }
        }
        if (helpersRemoved > 0) {
            sourceEmitHelpers.length -= helpersRemoved;
        }
    }
    ts.moveEmitHelpers = moveEmitHelpers;
    /* @internal */
    function compareEmitHelpers(x, y) {
        if (x === y)
            return 0 /* EqualTo */;
        if (x.priority === y.priority)
            return 0 /* EqualTo */;
        if (x.priority === undefined)
            return 1 /* GreaterThan */;
        if (y.priority === undefined)
            return -1 /* LessThan */;
        return ts.compareValues(x.priority, y.priority);
    }
    ts.compareEmitHelpers = compareEmitHelpers;
    function setOriginalNode(node, original) {
        node.original = original;
        if (original) {
            var emitNode = original.emitNode;
            if (emitNode)
                node.emitNode = mergeEmitNode(emitNode, node.emitNode);
        }
        return node;
    }
    ts.setOriginalNode = setOriginalNode;
    function mergeEmitNode(sourceEmitNode, destEmitNode) {
        var flags = sourceEmitNode.flags, leadingComments = sourceEmitNode.leadingComments, trailingComments = sourceEmitNode.trailingComments, commentRange = sourceEmitNode.commentRange, sourceMapRange = sourceEmitNode.sourceMapRange, tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges, constantValue = sourceEmitNode.constantValue, helpers = sourceEmitNode.helpers;
        if (!destEmitNode)
            destEmitNode = {};
        // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
        if (leadingComments)
            destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments);
        if (trailingComments)
            destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments);
        if (flags)
            destEmitNode.flags = flags;
        if (commentRange)
            destEmitNode.commentRange = commentRange;
        if (sourceMapRange)
            destEmitNode.sourceMapRange = sourceMapRange;
        if (tokenSourceMapRanges)
            destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
        if (constantValue !== undefined)
            destEmitNode.constantValue = constantValue;
        if (helpers)
            destEmitNode.helpers = ts.addRange(destEmitNode.helpers, helpers);
        return destEmitNode;
    }
    function mergeTokenSourceMapRanges(sourceRanges, destRanges) {
        if (!destRanges)
            destRanges = [];
        for (var key in sourceRanges) {
            destRanges[key] = sourceRanges[key];
        }
        return destRanges;
    }
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    ts.nullTransformationContext = {
        enableEmitNotification: ts.noop,
        enableSubstitution: ts.noop,
        endLexicalEnvironment: function () { return undefined; },
        getCompilerOptions: ts.notImplemented,
        getEmitHost: ts.notImplemented,
        getEmitResolver: ts.notImplemented,
        hoistFunctionDeclaration: ts.noop,
        hoistVariableDeclaration: ts.noop,
        isEmitNotificationEnabled: ts.notImplemented,
        isSubstitutionEnabled: ts.notImplemented,
        onEmitNode: ts.noop,
        onSubstituteNode: ts.notImplemented,
        readEmitHelpers: ts.notImplemented,
        requestEmitHelper: ts.noop,
        resumeLexicalEnvironment: ts.noop,
        startLexicalEnvironment: ts.noop,
        suspendLexicalEnvironment: ts.noop
    };
    function createTypeCheck(value, tag) {
        return tag === "undefined"
            ? ts.createStrictEquality(value, ts.createVoidZero())
            : ts.createStrictEquality(ts.createTypeOf(value), ts.createLiteral(tag));
    }
    ts.createTypeCheck = createTypeCheck;
    function createMemberAccessForPropertyName(target, memberName, location) {
        if (ts.isComputedPropertyName(memberName)) {
            return ts.setTextRange(ts.createElementAccess(target, memberName.expression), location);
        }
        else {
            var expression = ts.setTextRange(ts.isIdentifier(memberName)
                ? ts.createPropertyAccess(target, memberName)
                : ts.createElementAccess(target, memberName), memberName);
            ts.getOrCreateEmitNode(expression).flags |= 64 /* NoNestedSourceMaps */;
            return expression;
        }
    }
    ts.createMemberAccessForPropertyName = createMemberAccessForPropertyName;
    function createFunctionCall(func, thisArg, argumentsList, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "call"), 
        /*typeArguments*/ undefined, [
            thisArg
        ].concat(argumentsList)), location);
    }
    ts.createFunctionCall = createFunctionCall;
    function createFunctionApply(func, thisArg, argumentsExpression, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "apply"), 
        /*typeArguments*/ undefined, [
            thisArg,
            argumentsExpression
        ]), location);
    }
    ts.createFunctionApply = createFunctionApply;
    function createArraySlice(array, start) {
        var argumentsList = [];
        if (start !== undefined) {
            argumentsList.push(typeof start === "number" ? ts.createLiteral(start) : start);
        }
        return ts.createCall(ts.createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList);
    }
    ts.createArraySlice = createArraySlice;
    function createArrayConcat(array, values) {
        return ts.createCall(ts.createPropertyAccess(array, "concat"), 
        /*typeArguments*/ undefined, values);
    }
    ts.createArrayConcat = createArrayConcat;
    function createMathPow(left, right, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Math"), "pow"), 
        /*typeArguments*/ undefined, [left, right]), location);
    }
    ts.createMathPow = createMathPow;
    function createReactNamespace(reactNamespace, parent) {
        // To ensure the emit resolver can properly resolve the namespace, we need to
        // treat this identifier as if it were a source tree node by clearing the `Synthesized`
        // flag and setting a parent node.
        var react = ts.createIdentifier(reactNamespace || "React");
        react.flags &= ~8 /* Synthesized */;
        // Set the parent that is in parse tree
        // this makes sure that parent chain is intact for checker to traverse complete scope tree
        react.parent = ts.getParseTreeNode(parent);
        return react;
    }
    function createJsxFactoryExpressionFromEntityName(jsxFactory, parent) {
        if (ts.isQualifiedName(jsxFactory)) {
            var left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
            var right = ts.createIdentifier(ts.idText(jsxFactory.right));
            right.escapedText = jsxFactory.right.escapedText;
            return ts.createPropertyAccess(left, right);
        }
        else {
            return createReactNamespace(ts.idText(jsxFactory), parent);
        }
    }
    function createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parent) {
        return jsxFactoryEntity ?
            createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
            ts.createPropertyAccess(createReactNamespace(reactNamespace, parent), "createElement");
    }
    function createExpressionForJsxElement(jsxFactoryEntity, reactNamespace, tagName, props, children, parentElement, location) {
        var argumentsList = [tagName];
        if (props) {
            argumentsList.push(props);
        }
        if (children && children.length > 0) {
            if (!props) {
                argumentsList.push(ts.createNull());
            }
            if (children.length > 1) {
                for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                    var child = children_1[_i];
                    child.startsOnNewLine = true;
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxElement = createExpressionForJsxElement;
    // Helpers
    function getHelperName(name) {
        return ts.setEmitFlags(ts.createIdentifier(name), 4096 /* HelperName */ | 2 /* AdviseOnEmitNode */);
    }
    ts.getHelperName = getHelperName;
    var valuesHelper = {
        name: "typescript:values",
        scoped: false,
        text: "\n            var __values = (this && this.__values) || function (o) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\n                if (m) return m.call(o);\n                return {\n                    next: function () {\n                        if (o && i >= o.length) o = void 0;\n                        return { value: o && o[i++], done: !o };\n                    }\n                };\n            };\n        "
    };
    function createValuesHelper(context, expression, location) {
        context.requestEmitHelper(valuesHelper);
        return ts.setTextRange(ts.createCall(getHelperName("__values"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.createValuesHelper = createValuesHelper;
    var readHelper = {
        name: "typescript:read",
        scoped: false,
        text: "\n            var __read = (this && this.__read) || function (o, n) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n                if (!m) return o;\n                var i = m.call(o), r, ar = [], e;\n                try {\n                    while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n                }\n                catch (error) { e = { error: error }; }\n                finally {\n                    try {\n                        if (r && !r.done && (m = i[\"return\"])) m.call(i);\n                    }\n                    finally { if (e) throw e.error; }\n                }\n                return ar;\n            };\n        "
    };
    function createReadHelper(context, iteratorRecord, count, location) {
        context.requestEmitHelper(readHelper);
        return ts.setTextRange(ts.createCall(getHelperName("__read"), 
        /*typeArguments*/ undefined, count !== undefined
            ? [iteratorRecord, ts.createLiteral(count)]
            : [iteratorRecord]), location);
    }
    ts.createReadHelper = createReadHelper;
    var spreadHelper = {
        name: "typescript:spread",
        scoped: false,
        text: "\n            var __spread = (this && this.__spread) || function () {\n                for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n                return ar;\n            };"
    };
    function createSpreadHelper(context, argumentList, location) {
        context.requestEmitHelper(readHelper);
        context.requestEmitHelper(spreadHelper);
        return ts.setTextRange(ts.createCall(getHelperName("__spread"), 
        /*typeArguments*/ undefined, argumentList), location);
    }
    ts.createSpreadHelper = createSpreadHelper;
    // Utilities
    function createForOfBindingStatement(node, boundValue) {
        if (ts.isVariableDeclarationList(node)) {
            var firstDeclaration = ts.firstOrUndefined(node.declarations);
            var updatedDeclaration = ts.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, 
            /*typeNode*/ undefined, boundValue);
            return ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.updateVariableDeclarationList(node, [updatedDeclaration])), 
            /*location*/ node);
        }
        else {
            var updatedExpression = ts.setTextRange(ts.createAssignment(node, boundValue), /*location*/ node);
            return ts.setTextRange(ts.createStatement(updatedExpression), /*location*/ node);
        }
    }
    ts.createForOfBindingStatement = createForOfBindingStatement;
    function insertLeadingStatement(dest, source) {
        if (ts.isBlock(dest)) {
            return ts.updateBlock(dest, ts.setTextRange(ts.createNodeArray([source].concat(dest.statements)), dest.statements));
        }
        else {
            return ts.createBlock(ts.createNodeArray([dest, source]), /*multiLine*/ true);
        }
    }
    ts.insertLeadingStatement = insertLeadingStatement;
    function restoreEnclosingLabel(node, outermostLabeledStatement, afterRestoreLabelCallback) {
        if (!outermostLabeledStatement) {
            return node;
        }
        var updated = ts.updateLabel(outermostLabeledStatement, outermostLabeledStatement.label, outermostLabeledStatement.statement.kind === 222 /* LabeledStatement */
            ? restoreEnclosingLabel(node, outermostLabeledStatement.statement)
            : node);
        if (afterRestoreLabelCallback) {
            afterRestoreLabelCallback(outermostLabeledStatement);
        }
        return updated;
    }
    ts.restoreEnclosingLabel = restoreEnclosingLabel;
    function shouldBeCapturedInTempVariable(node, cacheIdentifiers) {
        var target = skipParentheses(node);
        switch (target.kind) {
            case 71 /* Identifier */:
                return cacheIdentifiers;
            case 99 /* ThisKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* StringLiteral */:
                return false;
            case 177 /* ArrayLiteralExpression */:
                var elements = target.elements;
                if (elements.length === 0) {
                    return false;
                }
                return true;
            case 178 /* ObjectLiteralExpression */:
                return target.properties.length > 0;
            default:
                return true;
        }
    }
    function createCallBinding(expression, recordTempVariable, languageVersion, cacheIdentifiers) {
        var callee = skipOuterExpressions(expression, 7 /* All */);
        var thisArg;
        var target;
        if (ts.isSuperProperty(callee)) {
            thisArg = ts.createThis();
            target = callee;
        }
        else if (callee.kind === 97 /* SuperKeyword */) {
            thisArg = ts.createThis();
            target = languageVersion < 2 /* ES2015 */
                ? ts.setTextRange(ts.createIdentifier("_super"), callee)
                : callee;
        }
        else if (ts.getEmitFlags(callee) & 4096 /* HelperName */) {
            thisArg = ts.createVoidZero();
            target = parenthesizeForAccess(callee);
        }
        else {
            switch (callee.kind) {
                case 179 /* PropertyAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a.b()` target is `(_a = a).b` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.name);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                case 180 /* ElementAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createElementAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                default: {
                    // for `a()` target is `a` and thisArg is `void 0`
                    thisArg = ts.createVoidZero();
                    target = parenthesizeForAccess(expression);
                    break;
                }
            }
        }
        return { target: target, thisArg: thisArg };
    }
    ts.createCallBinding = createCallBinding;
    function inlineExpressions(expressions) {
        // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
        // stack size exceeded" errors.
        return expressions.length > 10
            ? ts.createCommaList(expressions)
            : ts.reduceLeft(expressions, ts.createComma);
    }
    ts.inlineExpressions = inlineExpressions;
    function createExpressionFromEntityName(node) {
        if (ts.isQualifiedName(node)) {
            var left = createExpressionFromEntityName(node.left);
            var right = ts.getMutableClone(node.right);
            return ts.setTextRange(ts.createPropertyAccess(left, right), node);
        }
        else {
            return ts.getMutableClone(node);
        }
    }
    ts.createExpressionFromEntityName = createExpressionFromEntityName;
    function createExpressionForPropertyName(memberName) {
        if (ts.isIdentifier(memberName)) {
            return ts.createLiteral(memberName);
        }
        else if (ts.isComputedPropertyName(memberName)) {
            return ts.getMutableClone(memberName.expression);
        }
        else {
            return ts.getMutableClone(memberName);
        }
    }
    ts.createExpressionForPropertyName = createExpressionForPropertyName;
    function createExpressionForObjectLiteralElementLike(node, property, receiver) {
        switch (property.kind) {
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
                return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine);
            case 261 /* PropertyAssignment */:
                return createExpressionForPropertyAssignment(property, receiver);
            case 262 /* ShorthandPropertyAssignment */:
                return createExpressionForShorthandPropertyAssignment(property, receiver);
            case 151 /* MethodDeclaration */:
                return createExpressionForMethodDeclaration(property, receiver);
        }
    }
    ts.createExpressionForObjectLiteralElementLike = createExpressionForObjectLiteralElementLike;
    function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) {
        var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
        if (property === firstAccessor) {
            var properties_9 = [];
            if (getAccessor) {
                var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, getAccessor.parameters, 
                /*type*/ undefined, getAccessor.body);
                ts.setTextRange(getterFunction, getAccessor);
                ts.setOriginalNode(getterFunction, getAccessor);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                properties_9.push(getter);
            }
            if (setAccessor) {
                var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, setAccessor.parameters, 
                /*type*/ undefined, setAccessor.body);
                ts.setTextRange(setterFunction, setAccessor);
                ts.setOriginalNode(setterFunction, setAccessor);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                properties_9.push(setter);
            }
            properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue()));
            properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue()));
            var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                receiver,
                createExpressionForPropertyName(property.name),
                ts.createObjectLiteral(properties_9, multiLine)
            ]), 
            /*location*/ firstAccessor);
            return ts.aggregateTransformFlags(expression);
        }
        return undefined;
    }
    function createExpressionForPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), property.initializer), property), property));
    }
    function createExpressionForShorthandPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), ts.getSynthesizedClone(property.name)), 
        /*location*/ property), 
        /*original*/ property));
    }
    function createExpressionForMethodDeclaration(method, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(method.modifiers, method.asteriskToken, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, method.parameters, 
        /*type*/ undefined, method.body), 
        /*location*/ method), 
        /*original*/ method)), 
        /*location*/ method), 
        /*original*/ method));
    }
    /**
     * Gets the internal name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the body of an ES5 class function body. An internal name will *never*
     * be prefixed with an module or namespace export modifier like "exports." when emitted as an
     * expression. An internal name will also *never* be renamed due to a collision with a block
     * scoped variable.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getInternalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */ | 32768 /* InternalName */);
    }
    ts.getInternalName = getInternalName;
    /**
     * Gets whether an identifier should only be referred to by its internal name.
     */
    function isInternalName(node) {
        return (ts.getEmitFlags(node) & 32768 /* InternalName */) !== 0;
    }
    ts.isInternalName = isInternalName;
    /**
     * Gets the local name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
     * local name will *never* be prefixed with an module or namespace export modifier like
     * "exports." when emitted as an expression.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getLocalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */);
    }
    ts.getLocalName = getLocalName;
    /**
     * Gets whether an identifier should only be referred to by its local name.
     */
    function isLocalName(node) {
        return (ts.getEmitFlags(node) & 16384 /* LocalName */) !== 0;
    }
    ts.isLocalName = isLocalName;
    /**
     * Gets the export name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
     * export name will *always* be prefixed with an module or namespace export modifier like
     * `"exports."` when emitted as an expression if the name points to an exported symbol.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExportName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 8192 /* ExportName */);
    }
    ts.getExportName = getExportName;
    /**
     * Gets whether an identifier should only be referred to by its export representation if the
     * name points to an exported symbol.
     */
    function isExportName(node) {
        return (ts.getEmitFlags(node) & 8192 /* ExportName */) !== 0;
    }
    ts.isExportName = isExportName;
    /**
     * Gets the name of a declaration for use in declarations.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getDeclarationName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps);
    }
    ts.getDeclarationName = getDeclarationName;
    function getName(node, allowComments, allowSourceMaps, emitFlags) {
        var nodeName = ts.getNameOfDeclaration(node);
        if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) {
            var name = ts.getMutableClone(nodeName);
            emitFlags |= ts.getEmitFlags(nodeName);
            if (!allowSourceMaps)
                emitFlags |= 48 /* NoSourceMap */;
            if (!allowComments)
                emitFlags |= 1536 /* NoComments */;
            if (emitFlags)
                ts.setEmitFlags(name, emitFlags);
            return name;
        }
        return ts.getGeneratedNameForNode(node);
    }
    /**
     * Gets the exported name of a declaration for use in expressions.
     *
     * An exported name will *always* be prefixed with an module or namespace export modifier like
     * "exports." if the name points to an exported symbol.
     *
     * @param ns The namespace identifier.
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExternalModuleOrNamespaceExportName(ns, node, allowComments, allowSourceMaps) {
        if (ns && ts.hasModifier(node, 1 /* Export */)) {
            return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
        }
        return getExportName(node, allowComments, allowSourceMaps);
    }
    ts.getExternalModuleOrNamespaceExportName = getExternalModuleOrNamespaceExportName;
    /**
     * Gets a namespace-qualified name for use in expressions.
     *
     * @param ns The namespace identifier.
     * @param name The name.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getNamespaceMemberName(ns, name, allowComments, allowSourceMaps) {
        var qualifiedName = ts.createPropertyAccess(ns, ts.nodeIsSynthesized(name) ? name : ts.getSynthesizedClone(name));
        ts.setTextRange(qualifiedName, name);
        var emitFlags;
        if (!allowSourceMaps)
            emitFlags |= 48 /* NoSourceMap */;
        if (!allowComments)
            emitFlags |= 1536 /* NoComments */;
        if (emitFlags)
            ts.setEmitFlags(qualifiedName, emitFlags);
        return qualifiedName;
    }
    ts.getNamespaceMemberName = getNamespaceMemberName;
    function convertToFunctionBody(node, multiLine) {
        return ts.isBlock(node) ? node : ts.setTextRange(ts.createBlock([ts.setTextRange(ts.createReturn(node), node)], multiLine), node);
    }
    ts.convertToFunctionBody = convertToFunctionBody;
    function convertFunctionDeclarationToExpression(node) {
        ts.Debug.assert(!!node.body);
        var updated = ts.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
        ts.setOriginalNode(updated, node);
        ts.setTextRange(updated, node);
        if (node.startsOnNewLine) {
            updated.startsOnNewLine = true;
        }
        ts.aggregateTransformFlags(updated);
        return updated;
    }
    ts.convertFunctionDeclarationToExpression = convertFunctionDeclarationToExpression;
    function isUseStrictPrologue(node) {
        return ts.isStringLiteral(node.expression) && node.expression.text === "use strict";
    }
    /**
     * Add any necessary prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     *
     * @param target: result statements array
     * @param source: origin statements array
     * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
     * @param visitor: Optional callback used to visit any custom prologue directives.
     */
    function addPrologue(target, source, ensureUseStrict, visitor) {
        var offset = addStandardPrologue(target, source, ensureUseStrict);
        return addCustomPrologue(target, source, offset, visitor);
    }
    ts.addPrologue = addPrologue;
    /**
     * Add just the standard (string-expression) prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     */
    function addStandardPrologue(target, source, ensureUseStrict) {
        ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
        var foundUseStrict = false;
        var statementOffset = 0;
        var numStatements = source.length;
        while (statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    foundUseStrict = true;
                }
                target.push(statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        if (ensureUseStrict && !foundUseStrict) {
            target.push(startOnNewLine(ts.createStatement(ts.createLiteral("use strict"))));
        }
        return statementOffset;
    }
    ts.addStandardPrologue = addStandardPrologue;
    /**
     * Add just the custom prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     */
    function addCustomPrologue(target, source, statementOffset, visitor) {
        var numStatements = source.length;
        while (statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.getEmitFlags(statement) & 1048576 /* CustomPrologue */) {
                target.push(visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        return statementOffset;
    }
    ts.addCustomPrologue = addCustomPrologue;
    function startsWithUseStrict(statements) {
        var firstStatement = ts.firstOrUndefined(statements);
        return firstStatement !== undefined
            && ts.isPrologueDirective(firstStatement)
            && isUseStrictPrologue(firstStatement);
    }
    ts.startsWithUseStrict = startsWithUseStrict;
    /**
     * Ensures "use strict" directive is added
     *
     * @param statements An array of statements
     */
    function ensureUseStrict(statements) {
        var foundUseStrict = false;
        for (var _i = 0, statements_3 = statements; _i < statements_3.length; _i++) {
            var statement = statements_3[_i];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    foundUseStrict = true;
                    break;
                }
            }
            else {
                break;
            }
        }
        if (!foundUseStrict) {
            return ts.setTextRange(ts.createNodeArray([
                startOnNewLine(ts.createStatement(ts.createLiteral("use strict")))
            ].concat(statements)), statements);
        }
        return statements;
    }
    ts.ensureUseStrict = ensureUseStrict;
    /**
     * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
     * order of operations.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function parenthesizeBinaryOperand(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        var skipped = ts.skipPartiallyEmittedExpressions(operand);
        // If the resulting expression is already parenthesized, we do not need to do any further processing.
        if (skipped.kind === 185 /* ParenthesizedExpression */) {
            return operand;
        }
        return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand)
            ? ts.createParen(operand)
            : operand;
    }
    ts.parenthesizeBinaryOperand = parenthesizeBinaryOperand;
    /**
     * Determines whether the operand to a BinaryExpression needs to be parenthesized.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        // If the operand has lower precedence, then it needs to be parenthesized to preserve the
        // intent of the expression. For example, if the operand is `a + b` and the operator is
        // `*`, then we need to parenthesize the operand to preserve the intended order of
        // operations: `(a + b) * x`.
        //
        // If the operand has higher precedence, then it does not need to be parenthesized. For
        // example, if the operand is `a * b` and the operator is `+`, then we do not need to
        // parenthesize to preserve the intended order of operations: `a * b + x`.
        //
        // If the operand has the same precedence, then we need to check the associativity of
        // the operator based on whether this is the left or right operand of the expression.
        //
        // For example, if `a / d` is on the right of operator `*`, we need to parenthesize
        // to preserve the intended order of operations: `x * (a / d)`
        //
        // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve
        // the intended order of operations: `(a ** b) ** c`
        var binaryOperatorPrecedence = ts.getOperatorPrecedence(194 /* BinaryExpression */, binaryOperator);
        var binaryOperatorAssociativity = ts.getOperatorAssociativity(194 /* BinaryExpression */, binaryOperator);
        var emittedOperand = ts.skipPartiallyEmittedExpressions(operand);
        var operandPrecedence = ts.getExpressionPrecedence(emittedOperand);
        switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) {
            case -1 /* LessThan */:
                // If the operand is the right side of a right-associative binary operation
                // and is a yield expression, then we do not need parentheses.
                if (!isLeftSideOfBinary
                    && binaryOperatorAssociativity === 1 /* Right */
                    && operand.kind === 197 /* YieldExpression */) {
                    return false;
                }
                return true;
            case 1 /* GreaterThan */:
                return false;
            case 0 /* EqualTo */:
                if (isLeftSideOfBinary) {
                    // No need to parenthesize the left operand when the binary operator is
                    // left associative:
                    //  (a*b)/x    ->  a*b/x
                    //  (a**b)/x   ->  a**b/x
                    //
                    // Parentheses are needed for the left operand when the binary operator is
                    // right associative:
                    //  (a/b)**x   ->  (a/b)**x
                    //  (a**b)**x  ->  (a**b)**x
                    return binaryOperatorAssociativity === 1 /* Right */;
                }
                else {
                    if (ts.isBinaryExpression(emittedOperand)
                        && emittedOperand.operatorToken.kind === binaryOperator) {
                        // No need to parenthesize the right operand when the binary operator and
                        // operand are the same and one of the following:
                        //  x*(a*b)     => x*a*b
                        //  x|(a|b)     => x|a|b
                        //  x&(a&b)     => x&a&b
                        //  x^(a^b)     => x^a^b
                        if (operatorHasAssociativeProperty(binaryOperator)) {
                            return false;
                        }
                        // No need to parenthesize the right operand when the binary operator
                        // is plus (+) if both the left and right operands consist solely of either
                        // literals of the same kind or binary plus (+) expressions for literals of
                        // the same kind (recursively).
                        //  "a"+(1+2)       => "a"+(1+2)
                        //  "a"+("b"+"c")   => "a"+"b"+"c"
                        if (binaryOperator === 37 /* PlusToken */) {
                            var leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : 0 /* Unknown */;
                            if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) {
                                return false;
                            }
                        }
                    }
                    // No need to parenthesize the right operand when the operand is right
                    // associative:
                    //  x/(a**b)    -> x/a**b
                    //  x**(a**b)   -> x**a**b
                    //
                    // Parentheses are needed for the right operand when the operand is left
                    // associative:
                    //  x/(a*b)     -> x/(a*b)
                    //  x**(a/b)    -> x**(a/b)
                    var operandAssociativity = ts.getExpressionAssociativity(emittedOperand);
                    return operandAssociativity === 0 /* Left */;
                }
        }
    }
    /**
     * Determines whether a binary operator is mathematically associative.
     *
     * @param binaryOperator The binary operator.
     */
    function operatorHasAssociativeProperty(binaryOperator) {
        // The following operators are associative in JavaScript:
        //  (a*b)*c     -> a*(b*c)  -> a*b*c
        //  (a|b)|c     -> a|(b|c)  -> a|b|c
        //  (a&b)&c     -> a&(b&c)  -> a&b&c
        //  (a^b)^c     -> a^(b^c)  -> a^b^c
        //
        // While addition is associative in mathematics, JavaScript's `+` is not
        // guaranteed to be associative as it is overloaded with string concatenation.
        return binaryOperator === 39 /* AsteriskToken */
            || binaryOperator === 49 /* BarToken */
            || binaryOperator === 48 /* AmpersandToken */
            || binaryOperator === 50 /* CaretToken */;
    }
    /**
     * This function determines whether an expression consists of a homogeneous set of
     * literal expressions or binary plus expressions that all share the same literal kind.
     * It is used to determine whether the right-hand operand of a binary plus expression can be
     * emitted without parentheses.
     */
    function getLiteralKindOfBinaryPlusOperand(node) {
        node = ts.skipPartiallyEmittedExpressions(node);
        if (ts.isLiteralKind(node.kind)) {
            return node.kind;
        }
        if (node.kind === 194 /* BinaryExpression */ && node.operatorToken.kind === 37 /* PlusToken */) {
            if (node.cachedLiteralKind !== undefined) {
                return node.cachedLiteralKind;
            }
            var leftKind = getLiteralKindOfBinaryPlusOperand(node.left);
            var literalKind = ts.isLiteralKind(leftKind)
                && leftKind === getLiteralKindOfBinaryPlusOperand(node.right)
                ? leftKind
                : 0 /* Unknown */;
            node.cachedLiteralKind = literalKind;
            return literalKind;
        }
        return 0 /* Unknown */;
    }
    function parenthesizeForConditionalHead(condition) {
        var conditionalPrecedence = ts.getOperatorPrecedence(195 /* ConditionalExpression */, 55 /* QuestionToken */);
        var emittedCondition = ts.skipPartiallyEmittedExpressions(condition);
        var conditionPrecedence = ts.getExpressionPrecedence(emittedCondition);
        if (ts.compareValues(conditionPrecedence, conditionalPrecedence) === -1 /* LessThan */) {
            return ts.createParen(condition);
        }
        return condition;
    }
    ts.parenthesizeForConditionalHead = parenthesizeForConditionalHead;
    function parenthesizeSubexpressionOfConditionalExpression(e) {
        // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions
        // so in case when comma expression is introduced as a part of previous transformations
        // if should be wrapped in parens since comma operator has the lowest precedence
        return e.kind === 194 /* BinaryExpression */ && e.operatorToken.kind === 26 /* CommaToken */
            ? ts.createParen(e)
            : e;
    }
    ts.parenthesizeSubexpressionOfConditionalExpression = parenthesizeSubexpressionOfConditionalExpression;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression
     * as the expression of a NewExpression node.
     *
     * @param expression The Expression node.
     */
    function parenthesizeForNew(expression) {
        var leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true);
        switch (leftmostExpr.kind) {
            case 181 /* CallExpression */:
                return ts.createParen(expression);
            case 182 /* NewExpression */:
                return !leftmostExpr.arguments
                    ? ts.createParen(expression)
                    : expression;
        }
        return parenthesizeForAccess(expression);
    }
    ts.parenthesizeForNew = parenthesizeForNew;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression for
     * property or element access.
     *
     * @param expr The expression node.
     */
    function parenthesizeForAccess(expression) {
        // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
        // to parenthesize the expression before a dot. The known exception is:
        //
        //    NewExpression:
        //       new C.x        -> not the same as (new C).x
        //
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isLeftHandSideExpression(emittedExpression)
            && (emittedExpression.kind !== 182 /* NewExpression */ || emittedExpression.arguments)) {
            return expression;
        }
        return ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeForAccess = parenthesizeForAccess;
    function parenthesizePostfixOperand(operand) {
        return ts.isLeftHandSideExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePostfixOperand = parenthesizePostfixOperand;
    function parenthesizePrefixOperand(operand) {
        return ts.isUnaryExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePrefixOperand = parenthesizePrefixOperand;
    function parenthesizeListElements(elements) {
        var result;
        for (var i = 0; i < elements.length; i++) {
            var element = parenthesizeExpressionForList(elements[i]);
            if (result !== undefined || element !== elements[i]) {
                if (result === undefined) {
                    result = elements.slice(0, i);
                }
                result.push(element);
            }
        }
        if (result !== undefined) {
            return ts.setTextRange(ts.createNodeArray(result, elements.hasTrailingComma), elements);
        }
        return elements;
    }
    ts.parenthesizeListElements = parenthesizeListElements;
    function parenthesizeExpressionForList(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        var expressionPrecedence = ts.getExpressionPrecedence(emittedExpression);
        var commaPrecedence = ts.getOperatorPrecedence(194 /* BinaryExpression */, 26 /* CommaToken */);
        return expressionPrecedence > commaPrecedence
            ? expression
            : ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeExpressionForList = parenthesizeExpressionForList;
    function parenthesizeExpressionForExpressionStatement(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isCallExpression(emittedExpression)) {
            var callee = emittedExpression.expression;
            var kind = ts.skipPartiallyEmittedExpressions(callee).kind;
            if (kind === 186 /* FunctionExpression */ || kind === 187 /* ArrowFunction */) {
                var mutableCall = ts.getMutableClone(emittedExpression);
                mutableCall.expression = ts.setTextRange(ts.createParen(callee), callee);
                return recreateOuterExpressions(expression, mutableCall, 4 /* PartiallyEmittedExpressions */);
            }
        }
        var leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind;
        if (leftmostExpressionKind === 178 /* ObjectLiteralExpression */ || leftmostExpressionKind === 186 /* FunctionExpression */) {
            return ts.setTextRange(ts.createParen(expression), expression);
        }
        return expression;
    }
    ts.parenthesizeExpressionForExpressionStatement = parenthesizeExpressionForExpressionStatement;
    function parenthesizeElementTypeMember(member) {
        switch (member.kind) {
            case 166 /* UnionType */:
            case 167 /* IntersectionType */:
            case 160 /* FunctionType */:
            case 161 /* ConstructorType */:
                return ts.createParenthesizedType(member);
        }
        return member;
    }
    ts.parenthesizeElementTypeMember = parenthesizeElementTypeMember;
    function parenthesizeArrayTypeMember(member) {
        switch (member.kind) {
            case 162 /* TypeQuery */:
            case 170 /* TypeOperator */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeElementTypeMember(member);
    }
    ts.parenthesizeArrayTypeMember = parenthesizeArrayTypeMember;
    function parenthesizeElementTypeMembers(members) {
        return ts.createNodeArray(ts.sameMap(members, parenthesizeElementTypeMember));
    }
    ts.parenthesizeElementTypeMembers = parenthesizeElementTypeMembers;
    function parenthesizeTypeParameters(typeParameters) {
        if (ts.some(typeParameters)) {
            var params = [];
            for (var i = 0; i < typeParameters.length; ++i) {
                var entry = typeParameters[i];
                params.push(i === 0 && ts.isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
                    ts.createParenthesizedType(entry) :
                    entry);
            }
            return ts.createNodeArray(params);
        }
    }
    ts.parenthesizeTypeParameters = parenthesizeTypeParameters;
    function getLeftmostExpression(node, stopAtCallExpressions) {
        while (true) {
            switch (node.kind) {
                case 193 /* PostfixUnaryExpression */:
                    node = node.operand;
                    continue;
                case 194 /* BinaryExpression */:
                    node = node.left;
                    continue;
                case 195 /* ConditionalExpression */:
                    node = node.condition;
                    continue;
                case 181 /* CallExpression */:
                    if (stopAtCallExpressions) {
                        return node;
                    }
                // falls through
                case 180 /* ElementAccessExpression */:
                case 179 /* PropertyAccessExpression */:
                    node = node.expression;
                    continue;
                case 288 /* PartiallyEmittedExpression */:
                    node = node.expression;
                    continue;
            }
            return node;
        }
    }
    function parenthesizeConciseBody(body) {
        if (!ts.isBlock(body) && getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === 178 /* ObjectLiteralExpression */) {
            return ts.setTextRange(ts.createParen(body), body);
        }
        return body;
    }
    ts.parenthesizeConciseBody = parenthesizeConciseBody;
    var OuterExpressionKinds;
    (function (OuterExpressionKinds) {
        OuterExpressionKinds[OuterExpressionKinds["Parentheses"] = 1] = "Parentheses";
        OuterExpressionKinds[OuterExpressionKinds["Assertions"] = 2] = "Assertions";
        OuterExpressionKinds[OuterExpressionKinds["PartiallyEmittedExpressions"] = 4] = "PartiallyEmittedExpressions";
        OuterExpressionKinds[OuterExpressionKinds["All"] = 7] = "All";
    })(OuterExpressionKinds = ts.OuterExpressionKinds || (ts.OuterExpressionKinds = {}));
    function isOuterExpression(node, kinds) {
        if (kinds === void 0) { kinds = 7 /* All */; }
        switch (node.kind) {
            case 185 /* ParenthesizedExpression */:
                return (kinds & 1 /* Parentheses */) !== 0;
            case 184 /* TypeAssertionExpression */:
            case 202 /* AsExpression */:
            case 203 /* NonNullExpression */:
                return (kinds & 2 /* Assertions */) !== 0;
            case 288 /* PartiallyEmittedExpression */:
                return (kinds & 4 /* PartiallyEmittedExpressions */) !== 0;
        }
        return false;
    }
    ts.isOuterExpression = isOuterExpression;
    function skipOuterExpressions(node, kinds) {
        if (kinds === void 0) { kinds = 7 /* All */; }
        var previousNode;
        do {
            previousNode = node;
            if (kinds & 1 /* Parentheses */) {
                node = skipParentheses(node);
            }
            if (kinds & 2 /* Assertions */) {
                node = skipAssertions(node);
            }
            if (kinds & 4 /* PartiallyEmittedExpressions */) {
                node = ts.skipPartiallyEmittedExpressions(node);
            }
        } while (previousNode !== node);
        return node;
    }
    ts.skipOuterExpressions = skipOuterExpressions;
    function skipParentheses(node) {
        while (node.kind === 185 /* ParenthesizedExpression */) {
            node = node.expression;
        }
        return node;
    }
    ts.skipParentheses = skipParentheses;
    function skipAssertions(node) {
        while (ts.isAssertionExpression(node) || node.kind === 203 /* NonNullExpression */) {
            node = node.expression;
        }
        return node;
    }
    ts.skipAssertions = skipAssertions;
    function updateOuterExpression(outerExpression, expression) {
        switch (outerExpression.kind) {
            case 185 /* ParenthesizedExpression */: return ts.updateParen(outerExpression, expression);
            case 184 /* TypeAssertionExpression */: return ts.updateTypeAssertion(outerExpression, outerExpression.type, expression);
            case 202 /* AsExpression */: return ts.updateAsExpression(outerExpression, expression, outerExpression.type);
            case 203 /* NonNullExpression */: return ts.updateNonNullExpression(outerExpression, expression);
            case 288 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
        }
    }
    /**
     * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
     *
     * A parenthesized expression can be ignored when all of the following are true:
     *
     * - It's `pos` and `end` are not -1
     * - It does not have a custom source map range
     * - It does not have a custom comment range
     * - It does not have synthetic leading or trailing comments
     *
     * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
     * the expression to maintain precedence, a new parenthesized expression should be created automatically when
     * the containing expression is created/updated.
     */
    function isIgnorableParen(node) {
        return node.kind === 185 /* ParenthesizedExpression */
            && ts.nodeIsSynthesized(node)
            && ts.nodeIsSynthesized(ts.getSourceMapRange(node))
            && ts.nodeIsSynthesized(ts.getCommentRange(node))
            && !ts.some(ts.getSyntheticLeadingComments(node))
            && !ts.some(ts.getSyntheticTrailingComments(node));
    }
    function recreateOuterExpressions(outerExpression, innerExpression, kinds) {
        if (kinds === void 0) { kinds = 7 /* All */; }
        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
            return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
        }
        return innerExpression;
    }
    ts.recreateOuterExpressions = recreateOuterExpressions;
    function startOnNewLine(node) {
        node.startsOnNewLine = true;
        return node;
    }
    ts.startOnNewLine = startOnNewLine;
    function getExternalHelpersModuleName(node) {
        var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
        var emitNode = parseNode && parseNode.emitNode;
        return emitNode && emitNode.externalHelpersModuleName;
    }
    ts.getExternalHelpersModuleName = getExternalHelpersModuleName;
    function getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions, hasExportStarsToExportValues) {
        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) {
            var externalHelpersModuleName = getExternalHelpersModuleName(node);
            if (externalHelpersModuleName) {
                return externalHelpersModuleName;
            }
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            var create = hasExportStarsToExportValues
                && moduleKind !== ts.ModuleKind.System
                && moduleKind !== ts.ModuleKind.ES2015
                && moduleKind !== ts.ModuleKind.ESNext;
            if (!create) {
                var helpers = ts.getEmitHelpers(node);
                if (helpers) {
                    for (var _i = 0, helpers_2 = helpers; _i < helpers_2.length; _i++) {
                        var helper = helpers_2[_i];
                        if (!helper.scoped) {
                            create = true;
                            break;
                        }
                    }
                }
            }
            if (create) {
                var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
                var emitNode = ts.getOrCreateEmitNode(parseNode);
                return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = ts.createUniqueName(ts.externalHelpersModuleNameText));
            }
        }
    }
    ts.getOrCreateExternalHelpersModuleNameIfNeeded = getOrCreateExternalHelpersModuleNameIfNeeded;
    /**
     * Get the name of that target module from an import or export declaration
     */
    function getLocalNameForExternalImport(node, sourceFile) {
        var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
        if (namespaceDeclaration && !ts.isDefaultImport(node)) {
            var name = namespaceDeclaration.name;
            return ts.isGeneratedIdentifier(name) ? name : ts.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name));
        }
        if (node.kind === 238 /* ImportDeclaration */ && node.importClause) {
            return ts.getGeneratedNameForNode(node);
        }
        if (node.kind === 244 /* ExportDeclaration */ && node.moduleSpecifier) {
            return ts.getGeneratedNameForNode(node);
        }
        return undefined;
    }
    ts.getLocalNameForExternalImport = getLocalNameForExternalImport;
    /**
     * Get the name of a target module from an import/export declaration as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     *  3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System).
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function getExternalModuleNameLiteral(importNode, sourceFile, host, resolver, compilerOptions) {
        var moduleName = ts.getExternalModuleName(importNode);
        if (moduleName.kind === 9 /* StringLiteral */) {
            return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions)
                || tryRenameExternalModule(moduleName, sourceFile)
                || ts.getSynthesizedClone(moduleName);
        }
        return undefined;
    }
    ts.getExternalModuleNameLiteral = getExternalModuleNameLiteral;
    /**
     * Some bundlers (SystemJS builder) sometimes want to rename dependencies.
     * Here we check if alternative name was provided for a given moduleName and return it if possible.
     */
    function tryRenameExternalModule(moduleName, sourceFile) {
        var rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
        return rename && ts.createLiteral(rename);
    }
    /**
     * Get the name of a module as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function tryGetModuleNameFromFile(file, host, options) {
        if (!file) {
            return undefined;
        }
        if (file.moduleName) {
            return ts.createLiteral(file.moduleName);
        }
        if (!file.isDeclarationFile && (options.out || options.outFile)) {
            return ts.createLiteral(ts.getExternalModuleNameFromPath(host, file.fileName));
        }
        return undefined;
    }
    ts.tryGetModuleNameFromFile = tryGetModuleNameFromFile;
    function tryGetModuleNameFromDeclaration(declaration, host, resolver, compilerOptions) {
        return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
    }
    /**
     * Gets the initializer of an BindingOrAssignmentElement.
     */
    function getInitializerOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `1` in `let { a = 1 } = ...`
            // `1` in `let { a: b = 1 } = ...`
            // `1` in `let { a: {b} = 1 } = ...`
            // `1` in `let { a: [b] = 1 } = ...`
            // `1` in `let [a = 1] = ...`
            // `1` in `let [{a} = 1] = ...`
            // `1` in `let [[a] = 1] = ...`
            return bindingElement.initializer;
        }
        if (ts.isPropertyAssignment(bindingElement)) {
            // `1` in `({ a: b = 1 } = ...)`
            // `1` in `({ a: {b} = 1 } = ...)`
            // `1` in `({ a: [b] = 1 } = ...)`
            return ts.isAssignmentExpression(bindingElement.initializer, /*excludeCompoundAssignment*/ true)
                ? bindingElement.initializer.right
                : undefined;
        }
        if (ts.isShorthandPropertyAssignment(bindingElement)) {
            // `1` in `({ a = 1 } = ...)`
            return bindingElement.objectAssignmentInitializer;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `1` in `[a = 1] = ...`
            // `1` in `[{a} = 1] = ...`
            // `1` in `[[a] = 1] = ...`
            return bindingElement.right;
        }
        if (ts.isSpreadElement(bindingElement)) {
            // Recovery consistent with existing emit.
            return getInitializerOfBindingOrAssignmentElement(bindingElement.expression);
        }
    }
    ts.getInitializerOfBindingOrAssignmentElement = getInitializerOfBindingOrAssignmentElement;
    /**
     * Gets the name of an BindingOrAssignmentElement.
     */
    function getTargetOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `a` in `let { a } = ...`
            // `a` in `let { a = 1 } = ...`
            // `b` in `let { a: b } = ...`
            // `b` in `let { a: b = 1 } = ...`
            // `a` in `let { ...a } = ...`
            // `{b}` in `let { a: {b} } = ...`
            // `{b}` in `let { a: {b} = 1 } = ...`
            // `[b]` in `let { a: [b] } = ...`
            // `[b]` in `let { a: [b] = 1 } = ...`
            // `a` in `let [a] = ...`
            // `a` in `let [a = 1] = ...`
            // `a` in `let [...a] = ...`
            // `{a}` in `let [{a}] = ...`
            // `{a}` in `let [{a} = 1] = ...`
            // `[a]` in `let [[a]] = ...`
            // `[a]` in `let [[a] = 1] = ...`
            return bindingElement.name;
        }
        if (ts.isObjectLiteralElementLike(bindingElement)) {
            switch (bindingElement.kind) {
                case 261 /* PropertyAssignment */:
                    // `b` in `({ a: b } = ...)`
                    // `b` in `({ a: b = 1 } = ...)`
                    // `{b}` in `({ a: {b} } = ...)`
                    // `{b}` in `({ a: {b} = 1 } = ...)`
                    // `[b]` in `({ a: [b] } = ...)`
                    // `[b]` in `({ a: [b] = 1 } = ...)`
                    // `b.c` in `({ a: b.c } = ...)`
                    // `b.c` in `({ a: b.c = 1 } = ...)`
                    // `b[0]` in `({ a: b[0] } = ...)`
                    // `b[0]` in `({ a: b[0] = 1 } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.initializer);
                case 262 /* ShorthandPropertyAssignment */:
                    // `a` in `({ a } = ...)`
                    // `a` in `({ a = 1 } = ...)`
                    return bindingElement.name;
                case 263 /* SpreadAssignment */:
                    // `a` in `({ ...a } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
            }
            // no target
            return undefined;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `a` in `[a = 1] = ...`
            // `{a}` in `[{a} = 1] = ...`
            // `[a]` in `[[a] = 1] = ...`
            // `a.b` in `[a.b = 1] = ...`
            // `a[0]` in `[a[0] = 1] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.left);
        }
        if (ts.isSpreadElement(bindingElement)) {
            // `a` in `[...a] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
        }
        // `a` in `[a] = ...`
        // `{a}` in `[{a}] = ...`
        // `[a]` in `[[a]] = ...`
        // `a.b` in `[a.b] = ...`
        // `a[0]` in `[a[0]] = ...`
        return bindingElement;
    }
    ts.getTargetOfBindingOrAssignmentElement = getTargetOfBindingOrAssignmentElement;
    /**
     * Determines whether an BindingOrAssignmentElement is a rest element.
     */
    function getRestIndicatorOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 146 /* Parameter */:
            case 176 /* BindingElement */:
                // `...` in `let [...a] = ...`
                return bindingElement.dotDotDotToken;
            case 198 /* SpreadElement */:
            case 263 /* SpreadAssignment */:
                // `...` in `[...a] = ...`
                return bindingElement;
        }
        return undefined;
    }
    ts.getRestIndicatorOfBindingOrAssignmentElement = getRestIndicatorOfBindingOrAssignmentElement;
    /**
     * Gets the property name of a BindingOrAssignmentElement
     */
    function getPropertyNameOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 176 /* BindingElement */:
                // `a` in `let { a: b } = ...`
                // `[a]` in `let { [a]: b } = ...`
                // `"a"` in `let { "a": b } = ...`
                // `1` in `let { 1: b } = ...`
                if (bindingElement.propertyName) {
                    var propertyName = bindingElement.propertyName;
                    return ts.isComputedPropertyName(propertyName) && ts.isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 261 /* PropertyAssignment */:
                // `a` in `({ a: b } = ...)`
                // `[a]` in `({ [a]: b } = ...)`
                // `"a"` in `({ "a": b } = ...)`
                // `1` in `({ 1: b } = ...)`
                if (bindingElement.name) {
                    var propertyName = bindingElement.name;
                    return ts.isComputedPropertyName(propertyName) && ts.isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 263 /* SpreadAssignment */:
                // `a` in `({ ...a } = ...)`
                return bindingElement.name;
        }
        var target = getTargetOfBindingOrAssignmentElement(bindingElement);
        if (target && ts.isPropertyName(target)) {
            return ts.isComputedPropertyName(target) && ts.isStringOrNumericLiteral(target.expression)
                ? target.expression
                : target;
        }
        ts.Debug.fail("Invalid property name for binding element.");
    }
    ts.getPropertyNameOfBindingOrAssignmentElement = getPropertyNameOfBindingOrAssignmentElement;
    /**
     * Gets the elements of a BindingOrAssignmentPattern
     */
    function getElementsOfBindingOrAssignmentPattern(name) {
        switch (name.kind) {
            case 174 /* ObjectBindingPattern */:
            case 175 /* ArrayBindingPattern */:
            case 177 /* ArrayLiteralExpression */:
                // `a` in `{a}`
                // `a` in `[a]`
                return name.elements;
            case 178 /* ObjectLiteralExpression */:
                // `a` in `{a}`
                return name.properties;
        }
    }
    ts.getElementsOfBindingOrAssignmentPattern = getElementsOfBindingOrAssignmentPattern;
    function convertToArrayAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpread(element.name), element), element);
            }
            var expression = convertToAssignmentElementTarget(element.name);
            return element.initializer
                ? ts.setOriginalNode(ts.setTextRange(ts.createAssignment(expression, element.initializer), element), element)
                : expression;
        }
        ts.Debug.assertNode(element, ts.isExpression);
        return element;
    }
    ts.convertToArrayAssignmentElement = convertToArrayAssignmentElement;
    function convertToObjectAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpreadAssignment(element.name), element), element);
            }
            if (element.propertyName) {
                var expression = convertToAssignmentElementTarget(element.name);
                return ts.setOriginalNode(ts.setTextRange(ts.createPropertyAssignment(element.propertyName, element.initializer ? ts.createAssignment(expression, element.initializer) : expression), element), element);
            }
            ts.Debug.assertNode(element.name, ts.isIdentifier);
            return ts.setOriginalNode(ts.setTextRange(ts.createShorthandPropertyAssignment(element.name, element.initializer), element), element);
        }
        ts.Debug.assertNode(element, ts.isObjectLiteralElementLike);
        return element;
    }
    ts.convertToObjectAssignmentElement = convertToObjectAssignmentElement;
    function convertToAssignmentPattern(node) {
        switch (node.kind) {
            case 175 /* ArrayBindingPattern */:
            case 177 /* ArrayLiteralExpression */:
                return convertToArrayAssignmentPattern(node);
            case 174 /* ObjectBindingPattern */:
            case 178 /* ObjectLiteralExpression */:
                return convertToObjectAssignmentPattern(node);
        }
    }
    ts.convertToAssignmentPattern = convertToAssignmentPattern;
    function convertToObjectAssignmentPattern(node) {
        if (ts.isObjectBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createObjectLiteral(ts.map(node.elements, convertToObjectAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isObjectLiteralExpression);
        return node;
    }
    ts.convertToObjectAssignmentPattern = convertToObjectAssignmentPattern;
    function convertToArrayAssignmentPattern(node) {
        if (ts.isArrayBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createArrayLiteral(ts.map(node.elements, convertToArrayAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isArrayLiteralExpression);
        return node;
    }
    ts.convertToArrayAssignmentPattern = convertToArrayAssignmentPattern;
    function convertToAssignmentElementTarget(node) {
        if (ts.isBindingPattern(node)) {
            return convertToAssignmentPattern(node);
        }
        ts.Debug.assertNode(node, ts.isExpression);
        return node;
    }
    ts.convertToAssignmentElementTarget = convertToAssignmentElementTarget;
})(ts || (ts = {}));
/// <reference path="checker.ts" />
/// <reference path="factory.ts" />
/// <reference path="utilities.ts" />
var ts;
(function (ts) {
    function visitNode(node, visitor, test, lift) {
        if (node === undefined || visitor === undefined) {
            return node;
        }
        ts.aggregateTransformFlags(node);
        var visited = visitor(node);
        if (visited === node) {
            return node;
        }
        var visitedNode;
        if (visited === undefined) {
            return undefined;
        }
        else if (ts.isArray(visited)) {
            visitedNode = (lift || extractSingleNode)(visited);
        }
        else {
            visitedNode = visited;
        }
        ts.Debug.assertNode(visitedNode, test);
        ts.aggregateTransformFlags(visitedNode);
        return visitedNode;
    }
    ts.visitNode = visitNode;
    /**
     * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
     *
     * @param nodes The NodeArray to visit.
     * @param visitor The callback used to visit a Node.
     * @param test A node test to execute for each node.
     * @param start An optional value indicating the starting offset at which to start visiting.
     * @param count An optional value indicating the maximum number of nodes to visit.
     */
    function visitNodes(nodes, visitor, test, start, count) {
        if (nodes === undefined || visitor === undefined) {
            return nodes;
        }
        var updated;
        // Ensure start and count have valid values
        var length = nodes.length;
        if (start === undefined || start < 0) {
            start = 0;
        }
        if (count === undefined || count > length - start) {
            count = length - start;
        }
        if (start > 0 || count < length) {
            // If we are not visiting all of the original nodes, we must always create a new array.
            // Since this is a fragment of a node array, we do not copy over the previous location
            // and will only copy over `hasTrailingComma` if we are including the last element.
            updated = ts.createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
        }
        // Visit each original node.
        for (var i = 0; i < count; i++) {
            var node = nodes[i + start];
            ts.aggregateTransformFlags(node);
            var visited = node !== undefined ? visitor(node) : undefined;
            if (updated !== undefined || visited === undefined || visited !== node) {
                if (updated === undefined) {
                    // Ensure we have a copy of `nodes`, up to the current index.
                    updated = ts.createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
                    ts.setTextRange(updated, nodes);
                }
                if (visited) {
                    if (ts.isArray(visited)) {
                        for (var _i = 0, visited_1 = visited; _i < visited_1.length; _i++) {
                            var visitedNode = visited_1[_i];
                            ts.Debug.assertNode(visitedNode, test);
                            ts.aggregateTransformFlags(visitedNode);
                            updated.push(visitedNode);
                        }
                    }
                    else {
                        ts.Debug.assertNode(visited, test);
                        ts.aggregateTransformFlags(visited);
                        updated.push(visited);
                    }
                }
            }
        }
        return updated || nodes;
    }
    ts.visitNodes = visitNodes;
    /**
     * Starts a new lexical environment and visits a statement list, ending the lexical environment
     * and merging hoisted declarations upon completion.
     */
    function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict) {
        context.startLexicalEnvironment();
        statements = visitNodes(statements, visitor, ts.isStatement, start);
        if (ensureUseStrict && !ts.startsWithUseStrict(statements)) {
            statements = ts.setTextRange(ts.createNodeArray([ts.createStatement(ts.createLiteral("use strict"))].concat(statements)), statements);
        }
        var declarations = context.endLexicalEnvironment();
        return ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, declarations)), statements);
    }
    ts.visitLexicalEnvironment = visitLexicalEnvironment;
    /**
     * Starts a new lexical environment and visits a parameter list, suspending the lexical
     * environment upon completion.
     */
    function visitParameterList(nodes, visitor, context, nodesVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        context.startLexicalEnvironment();
        var updated = nodesVisitor(nodes, visitor, ts.isParameterDeclaration);
        context.suspendLexicalEnvironment();
        return updated;
    }
    ts.visitParameterList = visitParameterList;
    function visitFunctionBody(node, visitor, context) {
        context.resumeLexicalEnvironment();
        var updated = visitNode(node, visitor, ts.isConciseBody);
        var declarations = context.endLexicalEnvironment();
        if (ts.some(declarations)) {
            var block = ts.convertToFunctionBody(updated);
            var statements = ts.mergeLexicalEnvironment(block.statements, declarations);
            return ts.updateBlock(block, statements);
        }
        return updated;
    }
    ts.visitFunctionBody = visitFunctionBody;
    function visitEachChild(node, visitor, context, nodesVisitor, tokenVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        if (node === undefined) {
            return undefined;
        }
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 142 /* LastToken */) || kind === 169 /* ThisType */) {
            return node;
        }
        switch (kind) {
            // Names
            case 71 /* Identifier */:
                return ts.updateIdentifier(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
            case 143 /* QualifiedName */:
                return ts.updateQualifiedName(node, visitNode(node.left, visitor, ts.isEntityName), visitNode(node.right, visitor, ts.isIdentifier));
            case 144 /* ComputedPropertyName */:
                return ts.updateComputedPropertyName(node, visitNode(node.expression, visitor, ts.isExpression));
            // Signature elements
            case 145 /* TypeParameter */:
                return ts.updateTypeParameterDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.constraint, visitor, ts.isTypeNode), visitNode(node.default, visitor, ts.isTypeNode));
            case 146 /* Parameter */:
                return ts.updateParameter(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 147 /* Decorator */:
                return ts.updateDecorator(node, visitNode(node.expression, visitor, ts.isExpression));
            // Type elements
            case 148 /* PropertySignature */:
                return ts.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 149 /* PropertyDeclaration */:
                return ts.updateProperty(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 150 /* MethodSignature */:
                return ts.updateMethodSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken));
            case 151 /* MethodDeclaration */:
                return ts.updateMethod(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 152 /* Constructor */:
                return ts.updateConstructor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 153 /* GetAccessor */:
                return ts.updateGetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 154 /* SetAccessor */:
                return ts.updateSetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 155 /* CallSignature */:
                return ts.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 156 /* ConstructSignature */:
                return ts.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 157 /* IndexSignature */:
                return ts.updateIndexSignature(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            // Types
            case 158 /* TypePredicate */:
                return ts.updateTypePredicateNode(node, visitNode(node.parameterName, visitor), visitNode(node.type, visitor, ts.isTypeNode));
            case 159 /* TypeReference */:
                return ts.updateTypeReferenceNode(node, visitNode(node.typeName, visitor, ts.isEntityName), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
            case 160 /* FunctionType */:
                return ts.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 161 /* ConstructorType */:
                return ts.updateConstructorTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 162 /* TypeQuery */:
                return ts.updateTypeQueryNode(node, visitNode(node.exprName, visitor, ts.isEntityName));
            case 163 /* TypeLiteral */:
                return ts.updateTypeLiteralNode(node, nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 164 /* ArrayType */:
                return ts.updateArrayTypeNode(node, visitNode(node.elementType, visitor, ts.isTypeNode));
            case 165 /* TupleType */:
                return ts.updateTypleTypeNode(node, nodesVisitor(node.elementTypes, visitor, ts.isTypeNode));
            case 166 /* UnionType */:
                return ts.updateUnionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 167 /* IntersectionType */:
                return ts.updateIntersectionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 168 /* ParenthesizedType */:
                return ts.updateParenthesizedType(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 170 /* TypeOperator */:
                return ts.updateTypeOperatorNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 171 /* IndexedAccessType */:
                return ts.updateIndexedAccessTypeNode(node, visitNode(node.objectType, visitor, ts.isTypeNode), visitNode(node.indexType, visitor, ts.isTypeNode));
            case 172 /* MappedType */:
                return ts.updateMappedTypeNode(node, visitNode(node.readonlyToken, tokenVisitor, ts.isToken), visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode));
            case 173 /* LiteralType */:
                return ts.updateLiteralTypeNode(node, visitNode(node.literal, visitor, ts.isExpression));
            // Binding patterns
            case 174 /* ObjectBindingPattern */:
                return ts.updateObjectBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isBindingElement));
            case 175 /* ArrayBindingPattern */:
                return ts.updateArrayBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isArrayBindingElement));
            case 176 /* BindingElement */:
                return ts.updateBindingElement(node, visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.propertyName, visitor, ts.isPropertyName), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.initializer, visitor, ts.isExpression));
            // Expression
            case 177 /* ArrayLiteralExpression */:
                return ts.updateArrayLiteral(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            case 178 /* ObjectLiteralExpression */:
                return ts.updateObjectLiteral(node, nodesVisitor(node.properties, visitor, ts.isObjectLiteralElementLike));
            case 179 /* PropertyAccessExpression */:
                return ts.updatePropertyAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.name, visitor, ts.isIdentifier));
            case 180 /* ElementAccessExpression */:
                return ts.updateElementAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.argumentExpression, visitor, ts.isExpression));
            case 181 /* CallExpression */:
                return ts.updateCall(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 182 /* NewExpression */:
                return ts.updateNew(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 183 /* TaggedTemplateExpression */:
                return ts.updateTaggedTemplate(node, visitNode(node.tag, visitor, ts.isExpression), visitNode(node.template, visitor, ts.isTemplateLiteral));
            case 184 /* TypeAssertionExpression */:
                return ts.updateTypeAssertion(node, visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 185 /* ParenthesizedExpression */:
                return ts.updateParen(node, visitNode(node.expression, visitor, ts.isExpression));
            case 186 /* FunctionExpression */:
                return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 187 /* ArrowFunction */:
                return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context));
            case 188 /* DeleteExpression */:
                return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression));
            case 189 /* TypeOfExpression */:
                return ts.updateTypeOf(node, visitNode(node.expression, visitor, ts.isExpression));
            case 190 /* VoidExpression */:
                return ts.updateVoid(node, visitNode(node.expression, visitor, ts.isExpression));
            case 191 /* AwaitExpression */:
                return ts.updateAwait(node, visitNode(node.expression, visitor, ts.isExpression));
            case 192 /* PrefixUnaryExpression */:
                return ts.updatePrefix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 193 /* PostfixUnaryExpression */:
                return ts.updatePostfix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 194 /* BinaryExpression */:
                return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken));
            case 195 /* ConditionalExpression */:
                return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression));
            case 196 /* TemplateExpression */:
                return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan));
            case 197 /* YieldExpression */:
                return ts.updateYield(node, visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.expression, visitor, ts.isExpression));
            case 198 /* SpreadElement */:
                return ts.updateSpread(node, visitNode(node.expression, visitor, ts.isExpression));
            case 199 /* ClassExpression */:
                return ts.updateClassExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 201 /* ExpressionWithTypeArguments */:
                return ts.updateExpressionWithTypeArguments(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 202 /* AsExpression */:
                return ts.updateAsExpression(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.type, visitor, ts.isTypeNode));
            case 203 /* NonNullExpression */:
                return ts.updateNonNullExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 204 /* MetaProperty */:
                return ts.updateMetaProperty(node, visitNode(node.name, visitor, ts.isIdentifier));
            // Misc
            case 205 /* TemplateSpan */:
                return ts.updateTemplateSpan(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.literal, visitor, ts.isTemplateMiddleOrTemplateTail));
            // Element
            case 207 /* Block */:
                return ts.updateBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 208 /* VariableStatement */:
                return ts.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.declarationList, visitor, ts.isVariableDeclarationList));
            case 210 /* ExpressionStatement */:
                return ts.updateStatement(node, visitNode(node.expression, visitor, ts.isExpression));
            case 211 /* IfStatement */:
                return ts.updateIf(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.thenStatement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.elseStatement, visitor, ts.isStatement, ts.liftToBlock));
            case 212 /* DoStatement */:
                return ts.updateDo(node, visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.expression, visitor, ts.isExpression));
            case 213 /* WhileStatement */:
                return ts.updateWhile(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 214 /* ForStatement */:
                return ts.updateFor(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.condition, visitor, ts.isExpression), visitNode(node.incrementor, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 215 /* ForInStatement */:
                return ts.updateForIn(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 216 /* ForOfStatement */:
                return ts.updateForOf(node, node.awaitModifier, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 217 /* ContinueStatement */:
                return ts.updateContinue(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 218 /* BreakStatement */:
                return ts.updateBreak(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 219 /* ReturnStatement */:
                return ts.updateReturn(node, visitNode(node.expression, visitor, ts.isExpression));
            case 220 /* WithStatement */:
                return ts.updateWith(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 221 /* SwitchStatement */:
                return ts.updateSwitch(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.caseBlock, visitor, ts.isCaseBlock));
            case 222 /* LabeledStatement */:
                return ts.updateLabel(node, visitNode(node.label, visitor, ts.isIdentifier), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 223 /* ThrowStatement */:
                return ts.updateThrow(node, visitNode(node.expression, visitor, ts.isExpression));
            case 224 /* TryStatement */:
                return ts.updateTry(node, visitNode(node.tryBlock, visitor, ts.isBlock), visitNode(node.catchClause, visitor, ts.isCatchClause), visitNode(node.finallyBlock, visitor, ts.isBlock));
            case 226 /* VariableDeclaration */:
                return ts.updateVariableDeclaration(node, visitNode(node.name, visitor, ts.isBindingName), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 227 /* VariableDeclarationList */:
                return ts.updateVariableDeclarationList(node, nodesVisitor(node.declarations, visitor, ts.isVariableDeclaration));
            case 228 /* FunctionDeclaration */:
                return ts.updateFunctionDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 229 /* ClassDeclaration */:
                return ts.updateClassDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 230 /* InterfaceDeclaration */:
                return ts.updateInterfaceDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 231 /* TypeAliasDeclaration */:
                return ts.updateTypeAliasDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 232 /* EnumDeclaration */:
                return ts.updateEnumDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.members, visitor, ts.isEnumMember));
            case 233 /* ModuleDeclaration */:
                return ts.updateModuleDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.body, visitor, ts.isModuleBody));
            case 234 /* ModuleBlock */:
                return ts.updateModuleBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 235 /* CaseBlock */:
                return ts.updateCaseBlock(node, nodesVisitor(node.clauses, visitor, ts.isCaseOrDefaultClause));
            case 236 /* NamespaceExportDeclaration */:
                return ts.updateNamespaceExportDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 237 /* ImportEqualsDeclaration */:
                return ts.updateImportEqualsDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.moduleReference, visitor, ts.isModuleReference));
            case 238 /* ImportDeclaration */:
                return ts.updateImportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.importClause, visitor, ts.isImportClause), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
            case 239 /* ImportClause */:
                return ts.updateImportClause(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.namedBindings, visitor, ts.isNamedImportBindings));
            case 240 /* NamespaceImport */:
                return ts.updateNamespaceImport(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 241 /* NamedImports */:
                return ts.updateNamedImports(node, nodesVisitor(node.elements, visitor, ts.isImportSpecifier));
            case 242 /* ImportSpecifier */:
                return ts.updateImportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            case 243 /* ExportAssignment */:
                return ts.updateExportAssignment(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.expression, visitor, ts.isExpression));
            case 244 /* ExportDeclaration */:
                return ts.updateExportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.exportClause, visitor, ts.isNamedExports), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
            case 245 /* NamedExports */:
                return ts.updateNamedExports(node, nodesVisitor(node.elements, visitor, ts.isExportSpecifier));
            case 246 /* ExportSpecifier */:
                return ts.updateExportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            // Module references
            case 248 /* ExternalModuleReference */:
                return ts.updateExternalModuleReference(node, visitNode(node.expression, visitor, ts.isExpression));
            // JSX
            case 249 /* JsxElement */:
                return ts.updateJsxElement(node, visitNode(node.openingElement, visitor, ts.isJsxOpeningElement), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingElement, visitor, ts.isJsxClosingElement));
            case 250 /* JsxSelfClosingElement */:
                return ts.updateJsxSelfClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 251 /* JsxOpeningElement */:
                return ts.updateJsxOpeningElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 252 /* JsxClosingElement */:
                return ts.updateJsxClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression));
            case 253 /* JsxAttribute */:
                return ts.updateJsxAttribute(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.initializer, visitor, ts.isStringLiteralOrJsxExpression));
            case 254 /* JsxAttributes */:
                return ts.updateJsxAttributes(node, nodesVisitor(node.properties, visitor, ts.isJsxAttributeLike));
            case 255 /* JsxSpreadAttribute */:
                return ts.updateJsxSpreadAttribute(node, visitNode(node.expression, visitor, ts.isExpression));
            case 256 /* JsxExpression */:
                return ts.updateJsxExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            // Clauses
            case 257 /* CaseClause */:
                return ts.updateCaseClause(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.statements, visitor, ts.isStatement));
            case 258 /* DefaultClause */:
                return ts.updateDefaultClause(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 259 /* HeritageClause */:
                return ts.updateHeritageClause(node, nodesVisitor(node.types, visitor, ts.isExpressionWithTypeArguments));
            case 260 /* CatchClause */:
                return ts.updateCatchClause(node, visitNode(node.variableDeclaration, visitor, ts.isVariableDeclaration), visitNode(node.block, visitor, ts.isBlock));
            // Property assignments
            case 261 /* PropertyAssignment */:
                return ts.updatePropertyAssignment(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            case 262 /* ShorthandPropertyAssignment */:
                return ts.updateShorthandPropertyAssignment(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.objectAssignmentInitializer, visitor, ts.isExpression));
            case 263 /* SpreadAssignment */:
                return ts.updateSpreadAssignment(node, visitNode(node.expression, visitor, ts.isExpression));
            // Enum
            case 264 /* EnumMember */:
                return ts.updateEnumMember(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            // Top-level nodes
            case 265 /* SourceFile */:
                return ts.updateSourceFileNode(node, visitLexicalEnvironment(node.statements, visitor, context));
            // Transformation nodes
            case 288 /* PartiallyEmittedExpression */:
                return ts.updatePartiallyEmittedExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 289 /* CommaListExpression */:
                return ts.updateCommaList(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            default:
                // No need to visit nodes with no children.
                return node;
        }
    }
    ts.visitEachChild = visitEachChild;
    /**
     * Extracts the single node from a NodeArray.
     *
     * @param nodes The NodeArray.
     */
    function extractSingleNode(nodes) {
        ts.Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
        return ts.singleOrUndefined(nodes);
    }
})(ts || (ts = {}));
/* @internal */
(function (ts) {
    function reduceNode(node, f, initial) {
        return node ? f(initial, node) : initial;
    }
    function reduceNodeArray(nodes, f, initial) {
        return nodes ? f(initial, nodes) : initial;
    }
    /**
     * Similar to `reduceLeft`, performs a reduction against each child of a node.
     * NOTE: Unlike `forEachChild`, this does *not* visit every node.
     *
     * @param node The node containing the children to reduce.
     * @param initial The initial value to supply to the reduction.
     * @param f The callback function
     */
    function reduceEachChild(node, initial, cbNode, cbNodeArray) {
        if (node === undefined) {
            return initial;
        }
        var reduceNodes = cbNodeArray ? reduceNodeArray : ts.reduceLeft;
        var cbNodes = cbNodeArray || cbNode;
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 142 /* LastToken */)) {
            return initial;
        }
        // We do not yet support types.
        if ((kind >= 158 /* TypePredicate */ && kind <= 173 /* LiteralType */)) {
            return initial;
        }
        var result = initial;
        switch (node.kind) {
            // Leaf nodes
            case 206 /* SemicolonClassElement */:
            case 209 /* EmptyStatement */:
            case 200 /* OmittedExpression */:
            case 225 /* DebuggerStatement */:
            case 287 /* NotEmittedStatement */:
                // No need to visit nodes with no children.
                break;
            // Names
            case 143 /* QualifiedName */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 144 /* ComputedPropertyName */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Signature elements
            case 146 /* Parameter */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 147 /* Decorator */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Type member
            case 148 /* PropertySignature */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.questionToken, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 149 /* PropertyDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 151 /* MethodDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 152 /* Constructor */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 153 /* GetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 154 /* SetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            // Binding patterns
            case 174 /* ObjectBindingPattern */:
            case 175 /* ArrayBindingPattern */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 176 /* BindingElement */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Expression
            case 177 /* ArrayLiteralExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 178 /* ObjectLiteralExpression */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 179 /* PropertyAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 180 /* ElementAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.argumentExpression, cbNode, result);
                break;
            case 181 /* CallExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 182 /* NewExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 183 /* TaggedTemplateExpression */:
                result = reduceNode(node.tag, cbNode, result);
                result = reduceNode(node.template, cbNode, result);
                break;
            case 184 /* TypeAssertionExpression */:
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 186 /* FunctionExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 187 /* ArrowFunction */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 185 /* ParenthesizedExpression */:
            case 188 /* DeleteExpression */:
            case 189 /* TypeOfExpression */:
            case 190 /* VoidExpression */:
            case 191 /* AwaitExpression */:
            case 197 /* YieldExpression */:
            case 198 /* SpreadElement */:
            case 203 /* NonNullExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 192 /* PrefixUnaryExpression */:
            case 193 /* PostfixUnaryExpression */:
                result = reduceNode(node.operand, cbNode, result);
                break;
            case 194 /* BinaryExpression */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 195 /* ConditionalExpression */:
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.whenTrue, cbNode, result);
                result = reduceNode(node.whenFalse, cbNode, result);
                break;
            case 196 /* TemplateExpression */:
                result = reduceNode(node.head, cbNode, result);
                result = reduceNodes(node.templateSpans, cbNodes, result);
                break;
            case 199 /* ClassExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 201 /* ExpressionWithTypeArguments */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                break;
            case 202 /* AsExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                break;
            // Misc
            case 205 /* TemplateSpan */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.literal, cbNode, result);
                break;
            // Element
            case 207 /* Block */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 208 /* VariableStatement */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.declarationList, cbNode, result);
                break;
            case 210 /* ExpressionStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 211 /* IfStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.thenStatement, cbNode, result);
                result = reduceNode(node.elseStatement, cbNode, result);
                break;
            case 212 /* DoStatement */:
                result = reduceNode(node.statement, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 213 /* WhileStatement */:
            case 220 /* WithStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 214 /* ForStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.incrementor, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 215 /* ForInStatement */:
            case 216 /* ForOfStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 219 /* ReturnStatement */:
            case 223 /* ThrowStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 221 /* SwitchStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.caseBlock, cbNode, result);
                break;
            case 222 /* LabeledStatement */:
                result = reduceNode(node.label, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 224 /* TryStatement */:
                result = reduceNode(node.tryBlock, cbNode, result);
                result = reduceNode(node.catchClause, cbNode, result);
                result = reduceNode(node.finallyBlock, cbNode, result);
                break;
            case 226 /* VariableDeclaration */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 227 /* VariableDeclarationList */:
                result = reduceNodes(node.declarations, cbNodes, result);
                break;
            case 228 /* FunctionDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 229 /* ClassDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 232 /* EnumDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 233 /* ModuleDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 234 /* ModuleBlock */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 235 /* CaseBlock */:
                result = reduceNodes(node.clauses, cbNodes, result);
                break;
            case 237 /* ImportEqualsDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.moduleReference, cbNode, result);
                break;
            case 238 /* ImportDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.importClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            case 239 /* ImportClause */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.namedBindings, cbNode, result);
                break;
            case 240 /* NamespaceImport */:
                result = reduceNode(node.name, cbNode, result);
                break;
            case 241 /* NamedImports */:
            case 245 /* NamedExports */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 242 /* ImportSpecifier */:
            case 246 /* ExportSpecifier */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 243 /* ExportAssignment */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 244 /* ExportDeclaration */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.exportClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            // Module references
            case 248 /* ExternalModuleReference */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // JSX
            case 249 /* JsxElement */:
                result = reduceNode(node.openingElement, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingElement, cbNode, result);
                break;
            case 250 /* JsxSelfClosingElement */:
            case 251 /* JsxOpeningElement */:
                result = reduceNode(node.tagName, cbNode, result);
                result = reduceNode(node.attributes, cbNode, result);
                break;
            case 254 /* JsxAttributes */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 252 /* JsxClosingElement */:
                result = reduceNode(node.tagName, cbNode, result);
                break;
            case 253 /* JsxAttribute */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 255 /* JsxSpreadAttribute */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 256 /* JsxExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Clauses
            case 257 /* CaseClause */:
                result = reduceNode(node.expression, cbNode, result);
            // falls through
            case 258 /* DefaultClause */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 259 /* HeritageClause */:
                result = reduceNodes(node.types, cbNodes, result);
                break;
            case 260 /* CatchClause */:
                result = reduceNode(node.variableDeclaration, cbNode, result);
                result = reduceNode(node.block, cbNode, result);
                break;
            // Property assignments
            case 261 /* PropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 262 /* ShorthandPropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.objectAssignmentInitializer, cbNode, result);
                break;
            case 263 /* SpreadAssignment */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Enum
            case 264 /* EnumMember */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Top-level nodes
            case 265 /* SourceFile */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            // Transformation nodes
            case 288 /* PartiallyEmittedExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 289 /* CommaListExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            default:
                break;
        }
        return result;
    }
    ts.reduceEachChild = reduceEachChild;
    function mergeLexicalEnvironment(statements, declarations) {
        if (!ts.some(declarations)) {
            return statements;
        }
        return ts.isNodeArray(statements)
            ? ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, declarations)), statements)
            : ts.addRange(statements, declarations);
    }
    ts.mergeLexicalEnvironment = mergeLexicalEnvironment;
    /**
     * Lifts a NodeArray containing only Statement nodes to a block.
     *
     * @param nodes The NodeArray.
     */
    function liftToBlock(nodes) {
        Debug.assert(ts.every(nodes, ts.isStatement), "Cannot lift nodes to a Block.");
        return ts.singleOrUndefined(nodes) || ts.createBlock(nodes);
    }
    ts.liftToBlock = liftToBlock;
    /**
     * Aggregates the TransformFlags for a Node and its subtree.
     */
    function aggregateTransformFlags(node) {
        aggregateTransformFlagsForNode(node);
        return node;
    }
    ts.aggregateTransformFlags = aggregateTransformFlags;
    /**
     * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
     * computed first, then the transform flags for the current node are computed from the subtree
     * flags and the state of the current node. Finally, the transform flags of the node are
     * returned, excluding any flags that should not be included in its parent node's subtree
     * flags.
     */
    function aggregateTransformFlagsForNode(node) {
        if (node === undefined) {
            return 0 /* None */;
        }
        if (node.transformFlags & 536870912 /* HasComputedFlags */) {
            return node.transformFlags & ~ts.getTransformFlagsSubtreeExclusions(node.kind);
        }
        var subtreeFlags = aggregateTransformFlagsForSubtree(node);
        return ts.computeTransformFlagsForNode(node, subtreeFlags);
    }
    function aggregateTransformFlagsForNodeArray(nodes) {
        if (nodes === undefined) {
            return 0 /* None */;
        }
        var subtreeFlags = 0 /* None */;
        var nodeArrayFlags = 0 /* None */;
        for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
            var node = nodes_3[_i];
            subtreeFlags |= aggregateTransformFlagsForNode(node);
            nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
        }
        nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
        return subtreeFlags;
    }
    /**
     * Aggregates the transform flags for the subtree of a node.
     */
    function aggregateTransformFlagsForSubtree(node) {
        // We do not transform ambient declarations or types, so there is no need to
        // recursively aggregate transform flags.
        if (ts.hasModifier(node, 2 /* Ambient */) || (ts.isTypeNode(node) && node.kind !== 201 /* ExpressionWithTypeArguments */)) {
            return 0 /* None */;
        }
        // Aggregate the transform flags of each child.
        return reduceEachChild(node, 0 /* None */, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
    }
    /**
     * Aggregates the TransformFlags of a child node with the TransformFlags of its
     * siblings.
     */
    function aggregateTransformFlagsForChildNode(transformFlags, node) {
        return transformFlags | aggregateTransformFlagsForNode(node);
    }
    function aggregateTransformFlagsForChildNodes(transformFlags, nodes) {
        return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
    }
    var Debug;
    (function (Debug) {
        var isDebugInfoEnabled = false;
        Debug.failBadSyntaxKind = Debug.shouldAssert(1 /* Normal */)
            ? function (node, message) { return Debug.fail((message || "Unexpected node.") + "\r\nNode " + ts.formatSyntaxKind(node.kind) + " was unexpected.", Debug.failBadSyntaxKind); }
            : ts.noop;
        Debug.assertEachNode = Debug.shouldAssert(1 /* Normal */)
            ? function (nodes, test, message) { return Debug.assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", function () { return "Node array did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertEachNode); }
            : ts.noop;
        Debug.assertNode = Debug.shouldAssert(1 /* Normal */)
            ? function (node, test, message) { return Debug.assert(test === undefined || test(node), message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertNode); }
            : ts.noop;
        Debug.assertOptionalNode = Debug.shouldAssert(1 /* Normal */)
            ? function (node, test, message) { return Debug.assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertOptionalNode); }
            : ts.noop;
        Debug.assertOptionalToken = Debug.shouldAssert(1 /* Normal */)
            ? function (node, kind, message) { return Debug.assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " was not a '" + ts.formatSyntaxKind(kind) + "' token."; }, Debug.assertOptionalToken); }
            : ts.noop;
        Debug.assertMissingNode = Debug.shouldAssert(1 /* Normal */)
            ? function (node, message) { return Debug.assert(node === undefined, message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " was unexpected'."; }, Debug.assertMissingNode); }
            : ts.noop;
        /**
         * Injects debug information into frequently used types.
         */
        function enableDebugInfo() {
            if (isDebugInfoEnabled)
                return;
            // Add additional properties in debug mode to assist with debugging.
            Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, {
                "__debugFlags": { get: function () { return ts.formatSymbolFlags(this.flags); } }
            });
            Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, {
                "__debugFlags": { get: function () { return ts.formatTypeFlags(this.flags); } },
                "__debugObjectFlags": { get: function () { return this.flags & 32768 /* Object */ ? ts.formatObjectFlags(this.objectFlags) : ""; } },
                "__debugTypeToString": { value: function () { return this.checker.typeToString(this); } },
            });
            var nodeConstructors = [
                ts.objectAllocator.getNodeConstructor(),
                ts.objectAllocator.getIdentifierConstructor(),
                ts.objectAllocator.getTokenConstructor(),
                ts.objectAllocator.getSourceFileConstructor()
            ];
            for (var _i = 0, nodeConstructors_1 = nodeConstructors; _i < nodeConstructors_1.length; _i++) {
                var ctor = nodeConstructors_1[_i];
                if (!ctor.prototype.hasOwnProperty("__debugKind")) {
                    Object.defineProperties(ctor.prototype, {
                        "__debugKind": { get: function () { return ts.formatSyntaxKind(this.kind); } },
                        "__debugModifierFlags": { get: function () { return ts.formatModifierFlags(ts.getModifierFlagsNoCache(this)); } },
                        "__debugTransformFlags": { get: function () { return ts.formatTransformFlags(this.transformFlags); } },
                        "__debugEmitFlags": { get: function () { return ts.formatEmitFlags(ts.getEmitFlags(this)); } },
                        "__debugGetText": {
                            value: function (includeTrivia) {
                                if (ts.nodeIsSynthesized(this))
                                    return "";
                                var parseNode = ts.getParseTreeNode(this);
                                var sourceFile = parseNode && ts.getSourceFileOfNode(parseNode);
                                return sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
                            }
                        }
                    });
                }
            }
            isDebugInfoEnabled = true;
        }
        Debug.enableDebugInfo = enableDebugInfo;
    })(Debug = ts.Debug || (ts.Debug = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getOriginalNodeId(node) {
        node = ts.getOriginalNode(node);
        return node ? ts.getNodeId(node) : 0;
    }
    ts.getOriginalNodeId = getOriginalNodeId;
    function collectExternalModuleInfo(sourceFile, resolver, compilerOptions) {
        var externalImports = [];
        var exportSpecifiers = ts.createMultiMap();
        var exportedBindings = [];
        var uniqueExports = ts.createMap();
        var exportedNames;
        var hasExportDefault = false;
        var exportEquals = undefined;
        var hasExportStarsToExportValues = false;
        for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
            var node = _a[_i];
            switch (node.kind) {
                case 238 /* ImportDeclaration */:
                    // import "mod"
                    // import x from "mod"
                    // import * as x from "mod"
                    // import { x, y } from "mod"
                    externalImports.push(node);
                    break;
                case 237 /* ImportEqualsDeclaration */:
                    if (node.moduleReference.kind === 248 /* ExternalModuleReference */) {
                        // import x = require("mod")
                        externalImports.push(node);
                    }
                    break;
                case 244 /* ExportDeclaration */:
                    if (node.moduleSpecifier) {
                        if (!node.exportClause) {
                            // export * from "mod"
                            externalImports.push(node);
                            hasExportStarsToExportValues = true;
                        }
                        else {
                            // export { x, y } from "mod"
                            externalImports.push(node);
                        }
                    }
                    else {
                        // export { x, y }
                        for (var _b = 0, _c = node.exportClause.elements; _b < _c.length; _b++) {
                            var specifier = _c[_b];
                            if (!uniqueExports.get(ts.idText(specifier.name))) {
                                var name = specifier.propertyName || specifier.name;
                                exportSpecifiers.add(ts.idText(name), specifier);
                                var decl = resolver.getReferencedImportDeclaration(name)
                                    || resolver.getReferencedValueDeclaration(name);
                                if (decl) {
                                    multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
                                }
                                uniqueExports.set(ts.idText(specifier.name), true);
                                exportedNames = ts.append(exportedNames, specifier.name);
                            }
                        }
                    }
                    break;
                case 243 /* ExportAssignment */:
                    if (node.isExportEquals && !exportEquals) {
                        // export = x
                        exportEquals = node;
                    }
                    break;
                case 208 /* VariableStatement */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        for (var _d = 0, _e = node.declarationList.declarations; _d < _e.length; _d++) {
                            var decl = _e[_d];
                            exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
                        }
                    }
                    break;
                case 228 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default function() { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export function x() { }
                            var name = node.name;
                            if (!uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
                case 229 /* ClassDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default class { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export class x { }
                            var name = node.name;
                            if (name && !uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
            }
        }
        var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
        var externalHelpersImportDeclaration = externalHelpersModuleName && ts.createImportDeclaration(
        /*decorators*/ undefined, 
        /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText));
        if (externalHelpersImportDeclaration) {
            externalImports.unshift(externalHelpersImportDeclaration);
        }
        return { externalImports: externalImports, exportSpecifiers: exportSpecifiers, exportEquals: exportEquals, hasExportStarsToExportValues: hasExportStarsToExportValues, exportedBindings: exportedBindings, exportedNames: exportedNames, externalHelpersImportDeclaration: externalHelpersImportDeclaration };
    }
    ts.collectExternalModuleInfo = collectExternalModuleInfo;
    function collectExportedVariableInfo(decl, uniqueExports, exportedNames) {
        if (ts.isBindingPattern(decl.name)) {
            for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
                }
            }
        }
        else if (!ts.isGeneratedIdentifier(decl.name)) {
            var text = ts.idText(decl.name);
            if (!uniqueExports.get(text)) {
                uniqueExports.set(text, true);
                exportedNames = ts.append(exportedNames, decl.name);
            }
        }
        return exportedNames;
    }
    /** Use a sparse array as a multi-map. */
    function multiMapSparseArrayAdd(map, key, value) {
        var values = map[key];
        if (values) {
            values.push(value);
        }
        else {
            map[key] = values = [value];
        }
        return values;
    }
    /**
     * Used in the module transformer to check if an expression is reasonably without sideeffect,
     *  and thus better to copy into multiple places rather than to cache in a temporary variable
     *  - this is mostly subjective beyond the requirement that the expression not be sideeffecting
     */
    function isSimpleCopiableExpression(expression) {
        return expression.kind === 9 /* StringLiteral */ ||
            expression.kind === 8 /* NumericLiteral */ ||
            expression.kind === 13 /* NoSubstitutionTemplateLiteral */ ||
            ts.isKeyword(expression.kind) ||
            ts.isIdentifier(expression);
    }
    ts.isSimpleCopiableExpression = isSimpleCopiableExpression;
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
var ts;
(function (ts) {
    var FlattenLevel;
    (function (FlattenLevel) {
        FlattenLevel[FlattenLevel["All"] = 0] = "All";
        FlattenLevel[FlattenLevel["ObjectRest"] = 1] = "ObjectRest";
    })(FlattenLevel = ts.FlattenLevel || (ts.FlattenLevel = {}));
    /**
     * Flattens a DestructuringAssignment or a VariableDeclaration to an expression.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param level Indicates the extent to which flattening should occur.
     * @param needsValue An optional value indicating whether the value from the right-hand-side of
     * the destructuring assignment is needed as part of a larger expression.
     * @param createAssignmentCallback An optional callback used to create the assignment expression.
     */
    function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) {
        var location = node;
        var value;
        if (ts.isDestructuringAssignment(node)) {
            value = node.right;
            while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) {
                if (ts.isDestructuringAssignment(value)) {
                    location = node = value;
                    value = node.right;
                }
                else {
                    return value;
                }
            }
        }
        var expressions;
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: true,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern,
            createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern,
            createArrayBindingOrAssignmentElement: makeAssignmentElement,
            visitor: visitor
        };
        if (value) {
            value = ts.visitNode(value, visitor, ts.isExpression);
            if (needsValue) {
                // If the right-hand value of the destructuring assignment needs to be preserved (as
                // is the case when the destructuring assignment is part of a larger expression),
                // then we need to cache the right-hand value.
                //
                // The source map location for the assignment should point to the entire binary
                // expression.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
            }
            else if (ts.nodeIsSynthesized(node)) {
                // Generally, the source map location for a destructuring assignment is the root
                // expression.
                //
                // However, if the root expression is synthesized (as in the case
                // of the initializer when transforming a ForOfStatement), then the source map
                // location should point to the right-hand value of the expression.
                location = value;
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node));
        if (value && needsValue) {
            if (!ts.some(expressions)) {
                return value;
            }
            expressions.push(value);
        }
        return ts.aggregateTransformFlags(ts.inlineExpressions(expressions)) || ts.createOmittedExpression();
        function emitExpression(expression) {
            // NOTE: this completely disables source maps, but aligns with the behavior of
            //       `emitAssignment` in the old emitter.
            ts.setEmitFlags(expression, 64 /* NoNestedSourceMaps */);
            ts.aggregateTransformFlags(expression);
            expressions = ts.append(expressions, expression);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression);
            var expression = createAssignmentCallback
                ? createAssignmentCallback(target, value, location)
                : ts.setTextRange(ts.createAssignment(ts.visitNode(target, visitor, ts.isExpression), value), location);
            expression.original = original;
            emitExpression(expression);
        }
    }
    ts.flattenDestructuringAssignment = flattenDestructuringAssignment;
    /**
     * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param boundValue The value bound to the declaration.
     * @param skipInitializer A value indicating whether to ignore the initializer of `node`.
     * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line.
     * @param level Indicates the extent to which flattening should occur.
     */
    function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables, skipInitializer) {
        var pendingExpressions;
        var pendingDeclarations = [];
        var declarations = [];
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: hoistTempVariables,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayBindingPattern,
            createObjectBindingOrAssignmentPattern: makeObjectBindingPattern,
            createArrayBindingOrAssignmentElement: makeBindingElement,
            visitor: visitor
        };
        flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
        if (pendingExpressions) {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (hoistTempVariables) {
                var value = ts.inlineExpressions(pendingExpressions);
                pendingExpressions = undefined;
                emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined);
            }
            else {
                context.hoistVariableDeclaration(temp);
                var pendingDeclaration = ts.lastOrUndefined(pendingDeclarations);
                pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, ts.createAssignment(temp, pendingDeclaration.value));
                ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions);
                pendingDeclaration.value = temp;
            }
        }
        for (var _i = 0, pendingDeclarations_1 = pendingDeclarations; _i < pendingDeclarations_1.length; _i++) {
            var _a = pendingDeclarations_1[_i], pendingExpressions_1 = _a.pendingExpressions, name = _a.name, value = _a.value, location = _a.location, original = _a.original;
            var variable = ts.createVariableDeclaration(name, 
            /*type*/ undefined, pendingExpressions_1 ? ts.inlineExpressions(ts.append(pendingExpressions_1, value)) : value);
            variable.original = original;
            ts.setTextRange(variable, location);
            if (ts.isIdentifier(name)) {
                ts.setEmitFlags(variable, 64 /* NoNestedSourceMaps */);
            }
            ts.aggregateTransformFlags(variable);
            declarations.push(variable);
        }
        return declarations;
        function emitExpression(value) {
            pendingExpressions = ts.append(pendingExpressions, value);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, ts.isBindingName);
            if (pendingExpressions) {
                value = ts.inlineExpressions(ts.append(pendingExpressions, value));
                pendingExpressions = undefined;
            }
            pendingDeclarations.push({ pendingExpressions: pendingExpressions, name: target, value: value, location: location, original: original });
        }
    }
    ts.flattenDestructuringBinding = flattenDestructuringBinding;
    /**
     * Flattens a BindingOrAssignmentElement into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param element The element to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     * @param skipInitializer An optional value indicating whether to include the initializer
     * for the element.
     */
    function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) {
        if (!skipInitializer) {
            var initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression);
            if (initializer) {
                // Combine value and initializer
                value = value ? createDefaultValueCheck(flattenContext, value, initializer, location) : initializer;
            }
            else if (!value) {
                // Use 'void 0' in absence of value and initializer
                value = ts.createVoidZero();
            }
        }
        var bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element);
        if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) {
            flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) {
            flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else {
            flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element);
        }
    }
    /**
     * Flattens an ObjectBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ObjectBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (numElements !== 1) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var computedTempVariables;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element);
                if (flattenContext.level >= 1 /* ObjectRest */
                    && !(element.transformFlags & (524288 /* ContainsRest */ | 1048576 /* ContainsObjectRest */))
                    && !(ts.getTargetOfBindingOrAssignmentElement(element).transformFlags & (524288 /* ContainsRest */ | 1048576 /* ContainsObjectRest */))
                    && !ts.isComputedPropertyName(propertyName)) {
                    bindingElements = ts.append(bindingElements, element);
                }
                else {
                    if (bindingElements) {
                        flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                        bindingElements = undefined;
                    }
                    var rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
                    if (ts.isComputedPropertyName(propertyName)) {
                        computedTempVariables = ts.append(computedTempVariables, rhsValue.argumentExpression);
                    }
                    flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
                }
            }
            else if (i === numElements - 1) {
                if (bindingElements) {
                    flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                    bindingElements = undefined;
                }
                var rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
    }
    /**
     * Flattens an ArrayBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ArrayBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) {
            // Read the elements of the iterable into an array
            value = ensureIdentifier(flattenContext, ts.createReadHelper(flattenContext.context, value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
                ? undefined
                : numElements, location), 
            /*reuseIdentifierExpressions*/ false, location);
        }
        else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)
            || ts.every(elements, ts.isOmittedExpression)) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]",
            // then we will create temporary variable.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var restContainingElements;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (flattenContext.level >= 1 /* ObjectRest */) {
                // If an array pattern contains an ObjectRest, we must cache the result so that we
                // can perform the ObjectRest destructuring in a different declaration
                if (element.transformFlags & 1048576 /* ContainsObjectRest */) {
                    var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                    if (flattenContext.hoistTempVariables) {
                        flattenContext.context.hoistVariableDeclaration(temp);
                    }
                    restContainingElements = ts.append(restContainingElements, [temp, element]);
                    bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp));
                }
                else {
                    bindingElements = ts.append(bindingElements, element);
                }
            }
            else if (ts.isOmittedExpression(element)) {
                continue;
            }
            else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var rhsValue = ts.createElementAccess(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
            else if (i === numElements - 1) {
                var rhsValue = ts.createArraySlice(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
        if (restContainingElements) {
            for (var _i = 0, restContainingElements_1 = restContainingElements; _i < restContainingElements_1.length; _i++) {
                var _a = restContainingElements_1[_i], id = _a[0], element = _a[1];
                flattenBindingOrAssignmentElement(flattenContext, element, id, element);
            }
        }
    }
    /**
     * Creates an expression used to provide a default value if a value is `undefined` at runtime.
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value to test.
     * @param defaultValue The default value to use if `value` is `undefined` at runtime.
     * @param location The location to use for source maps and comments.
     */
    function createDefaultValueCheck(flattenContext, value, defaultValue, location) {
        value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
        return ts.createConditional(ts.createTypeCheck(value, "undefined"), defaultValue, value);
    }
    /**
     * Creates either a PropertyAccessExpression or an ElementAccessExpression for the
     * right-hand side of a transformed destructuring assignment.
     *
     * @link https://tc39.github.io/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value that is the source of the property.
     * @param propertyName The destructuring property name.
     */
    function createDestructuringPropertyAccess(flattenContext, value, propertyName) {
        if (ts.isComputedPropertyName(propertyName)) {
            var argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
            return ts.createElementAccess(value, argumentExpression);
        }
        else if (ts.isStringOrNumericLiteral(propertyName)) {
            var argumentExpression = ts.getSynthesizedClone(propertyName);
            argumentExpression.text = argumentExpression.text;
            return ts.createElementAccess(value, argumentExpression);
        }
        else {
            var name = ts.createIdentifier(ts.idText(propertyName));
            return ts.createPropertyAccess(value, name);
        }
    }
    /**
     * Ensures that there exists a declared identifier whose value holds the given expression.
     * This function is useful to ensure that the expression's value can be read from in subsequent expressions.
     * Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier.
     *
     * @param flattenContext Options used to control flattening.
     * @param value the expression whose value needs to be bound.
     * @param reuseIdentifierExpressions true if identifier expressions can simply be returned;
     * false if it is necessary to always emit an identifier.
     * @param location The location to use for source maps and comments.
     */
    function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) {
        if (ts.isIdentifier(value) && reuseIdentifierExpressions) {
            return value;
        }
        else {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (flattenContext.hoistTempVariables) {
                flattenContext.context.hoistVariableDeclaration(temp);
                flattenContext.emitExpression(ts.setTextRange(ts.createAssignment(temp, value), location));
            }
            else {
                flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
            }
            return temp;
        }
    }
    function makeArrayBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isArrayBindingElement);
        return ts.createArrayBindingPattern(elements);
    }
    function makeArrayAssignmentPattern(elements) {
        return ts.createArrayLiteral(ts.map(elements, ts.convertToArrayAssignmentElement));
    }
    function makeObjectBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isBindingElement);
        return ts.createObjectBindingPattern(elements);
    }
    function makeObjectAssignmentPattern(elements) {
        return ts.createObjectLiteral(ts.map(elements, ts.convertToObjectAssignmentElement));
    }
    function makeBindingElement(name) {
        return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
    }
    function makeAssignmentElement(name) {
        return name;
    }
    var restHelper = {
        name: "typescript:rest",
        scoped: false,
        text: "\n            var __rest = (this && this.__rest) || function (s, e) {\n                var t = {};\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n                    t[p] = s[p];\n                if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n                    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\n                        t[p[i]] = s[p[i]];\n                return t;\n            };"
    };
    /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
     * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
     */
    function createRestCall(context, value, elements, computedTempVariables, location) {
        context.requestEmitHelper(restHelper);
        var propertyNames = [];
        var computedTempVariableOffset = 0;
        for (var i = 0; i < elements.length - 1; i++) {
            var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]);
            if (propertyName) {
                if (ts.isComputedPropertyName(propertyName)) {
                    var temp = computedTempVariables[computedTempVariableOffset];
                    computedTempVariableOffset++;
                    // typeof _tmp === "symbol" ? _tmp : _tmp + ""
                    propertyNames.push(ts.createConditional(ts.createTypeCheck(temp, "symbol"), temp, ts.createAdd(temp, ts.createLiteral(""))));
                }
                else {
                    propertyNames.push(ts.createLiteral(propertyName));
                }
            }
        }
        return ts.createCall(ts.getHelperName("__rest"), 
        /*typeArguments*/ undefined, [
            value,
            ts.setTextRange(ts.createArrayLiteral(propertyNames), location)
        ]);
    }
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/// <reference path="./destructuring.ts" />
/*@internal*/
var ts;
(function (ts) {
    /**
     * Indicates whether to emit type metadata in the new format.
     */
    var USE_NEW_TYPE_METADATA_FORMAT = false;
    var TypeScriptSubstitutionFlags;
    (function (TypeScriptSubstitutionFlags) {
        /** Enables substitutions for decorated classes. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
        /** Enables substitutions for namespace exports. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NamespaceExports"] = 2] = "NamespaceExports";
        /* Enables substitutions for unqualified enum members */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NonQualifiedEnumMembers"] = 8] = "NonQualifiedEnumMembers";
    })(TypeScriptSubstitutionFlags || (TypeScriptSubstitutionFlags = {}));
    var ClassFacts;
    (function (ClassFacts) {
        ClassFacts[ClassFacts["None"] = 0] = "None";
        ClassFacts[ClassFacts["HasStaticInitializedProperties"] = 1] = "HasStaticInitializedProperties";
        ClassFacts[ClassFacts["HasConstructorDecorators"] = 2] = "HasConstructorDecorators";
        ClassFacts[ClassFacts["HasMemberDecorators"] = 4] = "HasMemberDecorators";
        ClassFacts[ClassFacts["IsExportOfNamespace"] = 8] = "IsExportOfNamespace";
        ClassFacts[ClassFacts["IsNamedExternalExport"] = 16] = "IsNamedExternalExport";
        ClassFacts[ClassFacts["IsDefaultExternalExport"] = 32] = "IsDefaultExternalExport";
        ClassFacts[ClassFacts["IsDerivedClass"] = 64] = "IsDerivedClass";
        ClassFacts[ClassFacts["UseImmediatelyInvokedFunctionExpression"] = 128] = "UseImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["HasAnyDecorators"] = 6] = "HasAnyDecorators";
        ClassFacts[ClassFacts["NeedsName"] = 5] = "NeedsName";
        ClassFacts[ClassFacts["MayNeedImmediatelyInvokedFunctionExpression"] = 7] = "MayNeedImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["IsExported"] = 56] = "IsExported";
    })(ClassFacts || (ClassFacts = {}));
    function transformTypeScript(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var strictNullChecks = typeof compilerOptions.strictNullChecks === "undefined" ? compilerOptions.strict : compilerOptions.strictNullChecks;
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        // Enable substitution for property/element access to emit const enum values.
        context.enableSubstitution(179 /* PropertyAccessExpression */);
        context.enableSubstitution(180 /* ElementAccessExpression */);
        // These variables contain state that changes as we descend into the tree.
        var currentSourceFile;
        var currentNamespace;
        var currentNamespaceContainerName;
        var currentScope;
        var currentScopeFirstDeclarationsOfName;
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * A map that keeps track of aliases created for classes with decorators to avoid issues
         * with the double-binding behavior of classes.
         */
        var classAliases;
        /**
         * Keeps track of whether  we are within any containing namespaces when performing
         * just-in-time substitution while printing an expression identifier.
         */
        var applicableSubstitutions;
        return transformSourceFile;
        /**
         * Transform TypeScript-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = saveStateAndInvoke(node, visitSourceFile);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            return visited;
        }
        /**
         * Visits a node, saving and restoring state variables on the stack.
         *
         * @param node The node to visit.
         */
        function saveStateAndInvoke(node, f) {
            // Save state
            var savedCurrentScope = currentScope;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            // Handle state changes before visiting a node.
            onBeforeVisitNode(node);
            var visited = f(node);
            // Restore state
            if (currentScope !== savedCurrentScope) {
                currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            }
            currentScope = savedCurrentScope;
            return visited;
        }
        /**
         * Performs actions that should always occur immediately before visiting a node.
         *
         * @param node The node to visit.
         */
        function onBeforeVisitNode(node) {
            switch (node.kind) {
                case 265 /* SourceFile */:
                case 235 /* CaseBlock */:
                case 234 /* ModuleBlock */:
                case 207 /* Block */:
                    currentScope = node;
                    currentScopeFirstDeclarationsOfName = undefined;
                    break;
                case 229 /* ClassDeclaration */:
                case 228 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 2 /* Ambient */)) {
                        break;
                    }
                    // Record these declarations provided that they have a name.
                    if (node.name) {
                        recordEmittedDeclarationInScope(node);
                    }
                    else {
                        // These nodes should always have names unless they are default-exports;
                        // however, class declaration parsing allows for undefined names, so syntactically invalid
                        // programs may also have an undefined name.
                        ts.Debug.assert(node.kind === 229 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */));
                    }
                    break;
            }
        }
        /**
         * General-purpose node visitor.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            return saveStateAndInvoke(node, visitorWorker);
        }
        /**
         * Visits and possibly transforms any node.
         *
         * @param node The node to visit.
         */
        function visitorWorker(node) {
            if (node.transformFlags & 1 /* TypeScript */) {
                // This node is explicitly marked as TypeScript, so we should transform the node.
                return visitTypeScript(node);
            }
            else if (node.transformFlags & 2 /* ContainsTypeScript */) {
                // This node contains TypeScript, so we should visit its children.
                return ts.visitEachChild(node, visitor, context);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            return saveStateAndInvoke(node, sourceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitorWorker(node) {
            switch (node.kind) {
                case 238 /* ImportDeclaration */:
                case 237 /* ImportEqualsDeclaration */:
                case 243 /* ExportAssignment */:
                case 244 /* ExportDeclaration */:
                    return visitEllidableStatement(node);
                default:
                    return visitorWorker(node);
            }
        }
        function visitEllidableStatement(node) {
            var parsed = ts.getParseTreeNode(node);
            if (parsed !== node) {
                // If the node has been transformed by a `before` transformer, perform no ellision on it
                // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
                return node;
            }
            switch (node.kind) {
                case 238 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 243 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 244 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                default:
                    ts.Debug.fail("Unhandled ellided statement");
            }
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitor(node) {
            return saveStateAndInvoke(node, namespaceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitorWorker(node) {
            if (node.kind === 244 /* ExportDeclaration */ ||
                node.kind === 238 /* ImportDeclaration */ ||
                node.kind === 239 /* ImportClause */ ||
                (node.kind === 237 /* ImportEqualsDeclaration */ &&
                    node.moduleReference.kind === 248 /* ExternalModuleReference */)) {
                // do not emit ES6 imports and exports since they are illegal inside a namespace
                return undefined;
            }
            else if (node.transformFlags & 1 /* TypeScript */ || ts.hasModifier(node, 1 /* Export */)) {
                // This node is explicitly marked as TypeScript, or is exported at the namespace
                // level, so we should transform the node.
                return visitTypeScript(node);
            }
            else if (node.transformFlags & 2 /* ContainsTypeScript */) {
                // This node contains TypeScript, so we should visit its children.
                return ts.visitEachChild(node, visitor, context);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitor(node) {
            return saveStateAndInvoke(node, classElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitorWorker(node) {
            switch (node.kind) {
                case 152 /* Constructor */:
                    // TypeScript constructors are transformed in `visitClassDeclaration`.
                    // We elide them here as `visitorWorker` checks transform flags, which could
                    // erronously include an ES6 constructor without TypeScript syntax.
                    return undefined;
                case 149 /* PropertyDeclaration */:
                case 157 /* IndexSignature */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 151 /* MethodDeclaration */:
                    // Fallback to the default visit behavior.
                    return visitorWorker(node);
                case 206 /* SemicolonClassElement */:
                    return node;
                default:
                    ts.Debug.failBadSyntaxKind(node);
                    return undefined;
            }
        }
        function modifierVisitor(node) {
            if (ts.modifierToFlag(node.kind) & 2270 /* TypeScriptModifier */) {
                return undefined;
            }
            else if (currentNamespace && node.kind === 84 /* ExportKeyword */) {
                return undefined;
            }
            return node;
        }
        /**
         * Branching visitor, visits a TypeScript syntax node.
         *
         * @param node The node to visit.
         */
        function visitTypeScript(node) {
            if (ts.hasModifier(node, 2 /* Ambient */) && ts.isStatement(node)) {
                // TypeScript ambient declarations are elided, but some comments may be preserved.
                // See the implementation of `getLeadingComments` in comments.ts for more details.
                return ts.createNotEmittedStatement(node);
            }
            switch (node.kind) {
                case 84 /* ExportKeyword */:
                case 79 /* DefaultKeyword */:
                    // ES6 export and default modifiers are elided when inside a namespace.
                    return currentNamespace ? undefined : node;
                case 114 /* PublicKeyword */:
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 117 /* AbstractKeyword */:
                case 76 /* ConstKeyword */:
                case 124 /* DeclareKeyword */:
                case 131 /* ReadonlyKeyword */:
                // TypeScript accessibility and readonly modifiers are elided.
                case 164 /* ArrayType */:
                case 165 /* TupleType */:
                case 163 /* TypeLiteral */:
                case 158 /* TypePredicate */:
                case 145 /* TypeParameter */:
                case 119 /* AnyKeyword */:
                case 122 /* BooleanKeyword */:
                case 136 /* StringKeyword */:
                case 133 /* NumberKeyword */:
                case 130 /* NeverKeyword */:
                case 105 /* VoidKeyword */:
                case 137 /* SymbolKeyword */:
                case 161 /* ConstructorType */:
                case 160 /* FunctionType */:
                case 162 /* TypeQuery */:
                case 159 /* TypeReference */:
                case 166 /* UnionType */:
                case 167 /* IntersectionType */:
                case 168 /* ParenthesizedType */:
                case 169 /* ThisType */:
                case 170 /* TypeOperator */:
                case 171 /* IndexedAccessType */:
                case 172 /* MappedType */:
                case 173 /* LiteralType */:
                // TypeScript type nodes are elided.
                case 157 /* IndexSignature */:
                // TypeScript index signatures are elided.
                case 147 /* Decorator */:
                // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration.
                case 231 /* TypeAliasDeclaration */:
                // TypeScript type-only declarations are elided.
                case 149 /* PropertyDeclaration */:
                // TypeScript property declarations are elided.
                case 236 /* NamespaceExportDeclaration */:
                    // TypeScript namespace export declarations are elided.
                    return undefined;
                case 152 /* Constructor */:
                    return visitConstructor(node);
                case 230 /* InterfaceDeclaration */:
                    // TypeScript interfaces are elided, but some comments may be preserved.
                    // See the implementation of `getLeadingComments` in comments.ts for more details.
                    return ts.createNotEmittedStatement(node);
                case 229 /* ClassDeclaration */:
                    // This is a class declaration with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - property declarations
                    // - index signatures
                    // - method overload signatures
                    return visitClassDeclaration(node);
                case 199 /* ClassExpression */:
                    // This is a class expression with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - property declarations
                    // - index signatures
                    // - method overload signatures
                    return visitClassExpression(node);
                case 259 /* HeritageClause */:
                    // This is a heritage clause with TypeScript syntax extensions.
                    //
                    // TypeScript heritage clause extensions include:
                    // - `implements` clause
                    return visitHeritageClause(node);
                case 201 /* ExpressionWithTypeArguments */:
                    // TypeScript supports type arguments on an expression in an `extends` heritage clause.
                    return visitExpressionWithTypeArguments(node);
                case 151 /* MethodDeclaration */:
                    // TypeScript method declarations may have decorators, modifiers
                    // or type annotations.
                    return visitMethodDeclaration(node);
                case 153 /* GetAccessor */:
                    // Get Accessors can have TypeScript modifiers, decorators, and type annotations.
                    return visitGetAccessor(node);
                case 154 /* SetAccessor */:
                    // Set Accessors can have TypeScript modifiers and type annotations.
                    return visitSetAccessor(node);
                case 228 /* FunctionDeclaration */:
                    // Typescript function declarations can have modifiers, decorators, and type annotations.
                    return visitFunctionDeclaration(node);
                case 186 /* FunctionExpression */:
                    // TypeScript function expressions can have modifiers and type annotations.
                    return visitFunctionExpression(node);
                case 187 /* ArrowFunction */:
                    // TypeScript arrow functions can have modifiers and type annotations.
                    return visitArrowFunction(node);
                case 146 /* Parameter */:
                    // This is a parameter declaration with TypeScript syntax extensions.
                    //
                    // TypeScript parameter declaration syntax extensions include:
                    // - decorators
                    // - accessibility modifiers
                    // - the question mark (?) token for optional parameters
                    // - type annotations
                    // - this parameters
                    return visitParameter(node);
                case 185 /* ParenthesizedExpression */:
                    // ParenthesizedExpressions are TypeScript if their expression is a
                    // TypeAssertion or AsExpression
                    return visitParenthesizedExpression(node);
                case 184 /* TypeAssertionExpression */:
                case 202 /* AsExpression */:
                    // TypeScript type assertions are removed, but their subtrees are preserved.
                    return visitAssertionExpression(node);
                case 181 /* CallExpression */:
                    return visitCallExpression(node);
                case 182 /* NewExpression */:
                    return visitNewExpression(node);
                case 203 /* NonNullExpression */:
                    // TypeScript non-null expressions are removed, but their subtrees are preserved.
                    return visitNonNullExpression(node);
                case 232 /* EnumDeclaration */:
                    // TypeScript enum declarations do not exist in ES6 and must be rewritten.
                    return visitEnumDeclaration(node);
                case 208 /* VariableStatement */:
                    // TypeScript namespace exports for variable statements must be transformed.
                    return visitVariableStatement(node);
                case 226 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 233 /* ModuleDeclaration */:
                    // TypeScript namespace declarations must be transformed.
                    return visitModuleDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    // TypeScript namespace or external module import.
                    return visitImportEqualsDeclaration(node);
                default:
                    ts.Debug.failBadSyntaxKind(node);
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
                !(ts.isExternalModule(node) && moduleKind >= ts.ModuleKind.ES2015);
            return ts.updateSourceFileNode(node, ts.visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
        }
        /**
         * Tests whether we should emit a __decorate call for a class declaration.
         */
        function shouldEmitDecorateCallForClass(node) {
            if (node.decorators && node.decorators.length > 0) {
                return true;
            }
            var constructor = ts.getFirstConstructorWithBody(node);
            if (constructor) {
                return ts.forEach(constructor.parameters, shouldEmitDecorateCallForParameter);
            }
            return false;
        }
        /**
         * Tests whether we should emit a __decorate call for a parameter declaration.
         */
        function shouldEmitDecorateCallForParameter(parameter) {
            return parameter.decorators !== undefined && parameter.decorators.length > 0;
        }
        function getClassFacts(node, staticProperties) {
            var facts = 0 /* None */;
            if (ts.some(staticProperties))
                facts |= 1 /* HasStaticInitializedProperties */;
            var extendsClauseElement = ts.getClassExtendsHeritageClauseElement(node);
            if (extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 95 /* NullKeyword */)
                facts |= 64 /* IsDerivedClass */;
            if (shouldEmitDecorateCallForClass(node))
                facts |= 2 /* HasConstructorDecorators */;
            if (ts.childIsDecorated(node))
                facts |= 4 /* HasMemberDecorators */;
            if (isExportOfNamespace(node))
                facts |= 8 /* IsExportOfNamespace */;
            else if (isDefaultExternalModuleExport(node))
                facts |= 32 /* IsDefaultExternalExport */;
            else if (isNamedExternalModuleExport(node))
                facts |= 16 /* IsNamedExternalExport */;
            if (languageVersion <= 1 /* ES5 */ && (facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */))
                facts |= 128 /* UseImmediatelyInvokedFunctionExpression */;
            return facts;
        }
        /**
         * Transforms a class declaration with TypeScript syntax into compatible ES6.
         *
         * This function will only be called when one of the following conditions are met:
         * - The class has decorators.
         * - The class has property declarations with initializers.
         * - The class contains a constructor that contains parameters with accessibility modifiers.
         * - The class is an export in a TypeScript namespace.
         *
         * @param node The node to transform.
         */
        function visitClassDeclaration(node) {
            var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
            var facts = getClassFacts(node, staticProperties);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                context.startLexicalEnvironment();
            }
            var name = node.name || (facts & 5 /* NeedsName */ ? ts.getGeneratedNameForNode(node) : undefined);
            var classStatement = facts & 2 /* HasConstructorDecorators */
                ? createClassDeclarationHeadWithDecorators(node, name, facts)
                : createClassDeclarationHeadWithoutDecorators(node, name, facts);
            var statements = [classStatement];
            // 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 (facts & 1 /* HasStaticInitializedProperties */) {
                addInitializedPropertyStatements(statements, staticProperties, facts & 128 /* UseImmediatelyInvokedFunctionExpression */ ? ts.getInternalName(node) : ts.getLocalName(node));
            }
            // Write any decorators of the node.
            addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
            addClassElementDecorationStatements(statements, node, /*isStatic*/ true);
            addConstructorDecorationStatement(statements, node);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the
                // 'es2015' transformer can properly nest static initializers and decorators. The result
                // looks something like:
                //
                //  var C = function () {
                //      class C {
                //      }
                //      C.static_prop = 1;
                //      return C;
                //  }();
                //
                var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentSourceFile.text, node.members.end), 18 /* CloseBraceToken */);
                var localName = ts.getInternalName(node);
                // The following partially-emitted expression exists purely to align our sourcemap
                // emit with the original emitter.
                var outer = ts.createPartiallyEmittedExpression(localName);
                outer.end = closingBraceLocation.end;
                ts.setEmitFlags(outer, 1536 /* NoComments */);
                var statement = ts.createReturn(outer);
                statement.pos = closingBraceLocation.pos;
                ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
                statements.push(statement);
                ts.addRange(statements, context.endLexicalEnvironment());
                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
                ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */);
                var varStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), 
                    /*type*/ undefined, iife)
                ]));
                ts.setOriginalNode(varStatement, node);
                ts.setCommentRange(varStatement, node);
                ts.setSourceMapRange(varStatement, ts.moveRangePastDecorators(node));
                ts.startOnNewLine(varStatement);
                statements = [varStatement];
            }
            // If the class is exported as part of a TypeScript namespace, emit the namespace export.
            // Otherwise, if the class was exported at the top level and was decorated, emit an export
            // declaration or export default for the class.
            if (facts & 8 /* IsExportOfNamespace */) {
                addExportMemberAssignment(statements, node);
            }
            else if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */ || facts & 2 /* HasConstructorDecorators */) {
                if (facts & 32 /* IsDefaultExternalExport */) {
                    statements.push(ts.createExportDefault(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
                else if (facts & 16 /* IsNamedExternalExport */) {
                    statements.push(ts.createExternalModuleExport(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
            }
            if (statements.length > 1) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(classStatement, ts.getEmitFlags(classStatement) | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Transforms a non-decorated class declaration and appends the resulting statements.
         *
         * @param node A ClassDeclaration node.
         * @param name The name of the class.
         * @param facts Precomputed facts about the class.
         */
        function createClassDeclarationHeadWithoutDecorators(node, name, facts) {
            //  ${modifiers} class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            // we do not emit modifiers on the declaration if we are emitting an IIFE
            var modifiers = !(facts & 128 /* UseImmediatelyInvokedFunctionExpression */)
                ? ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier)
                : undefined;
            var classDeclaration = ts.createClassDeclaration(
            /*decorators*/ undefined, modifiers, name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0));
            // To better align with the old emitter, we should not emit a trailing source map
            // entry if the class has static properties.
            var emitFlags = ts.getEmitFlags(node);
            if (facts & 1 /* HasStaticInitializedProperties */) {
                emitFlags |= 32 /* NoTrailingSourceMap */;
            }
            ts.setTextRange(classDeclaration, node);
            ts.setOriginalNode(classDeclaration, node);
            ts.setEmitFlags(classDeclaration, emitFlags);
            return classDeclaration;
        }
        /**
         * Transforms a decorated class declaration and appends the resulting statements. If
         * the class requires an alias to avoid issues with double-binding, the alias is returned.
         */
        function createClassDeclarationHeadWithDecorators(node, name, facts) {
            // When we emit an ES6 class that has a class decorator, we must tailor the
            // emit to certain specific cases.
            //
            // In the simplest case, we emit the class declaration as a let declaration, and
            // evaluate decorators after the close of the class body:
            //
            //  [Example 1]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  class C {                       | }
            //  }                               | C = __decorate([dec], C);
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export { C };
            //  ---------------------------------------------------------------------
            //
            // If a class declaration contains a reference to itself *inside* of the class body,
            // this introduces two bindings to the class: One outside of the class body, and one
            // inside of the class body. If we apply decorators as in [Example 1] above, there
            // is the possibility that the decorator `dec` will return a new value for the
            // constructor, which would result in the binding inside of the class no longer
            // pointing to the same reference as the binding outside of the class.
            //
            // As a result, we must instead rewrite all references to the class *inside* of the
            // class body to instead point to a local temporary alias for the class:
            //
            //  [Example 2]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = C_1 = class C {
            //  class C {                       |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export { C };
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            // If a class declaration is the default export of a module, we instead emit
            // the export after the decorated declaration:
            //
            //  [Example 3]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let default_1 = class {
            //  export default class {          | }
            //  }                               | default_1 = __decorate([dec], default_1);
            //                                  | export default default_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export default C;
            //  ---------------------------------------------------------------------
            //
            // If the class declaration is the default export and a reference to itself
            // inside of the class body, we must emit both an alias for the class *and*
            // move the export after the declaration:
            //
            //  [Example 4]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export default C;
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            var location = ts.moveRangePastDecorators(node);
            var classAlias = getClassAliasIfNeeded(node);
            var declName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  ... = class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
            var members = transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0);
            var classExpression = ts.createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, location);
            //  let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
            //                                         or decoratedClassAlias if the class contain self-reference.
            var statement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declName, 
                /*type*/ undefined, classAlias ? ts.createAssignment(classAlias, classExpression) : classExpression)
            ], 1 /* Let */));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, location);
            ts.setCommentRange(statement, node);
            return statement;
        }
        /**
         * Transforms a class expression with TypeScript syntax into compatible ES6.
         *
         * This function will only be called when one of the following conditions are met:
         * - The class has property declarations with initializers.
         * - The class contains a constructor that contains parameters with accessibility modifiers.
         *
         * @param node The node to transform.
         */
        function visitClassExpression(node) {
            var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
            var members = transformClassMembers(node, ts.some(heritageClauses, function (c) { return c.token === 85 /* ExtendsKeyword */; }));
            var classExpression = ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, heritageClauses, members);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, node);
            if (staticProperties.length > 0) {
                var expressions = [];
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                if (resolver.getNodeCheckFlags(node) & 8388608 /* ClassWithConstructorReference */) {
                    // record an alias as the class name is not in scope for statics.
                    enableSubstitutionForClassAliases();
                    classAliases[ts.getOriginalNodeId(node)] = ts.getSynthesizedClone(temp);
                }
                // To preserve the behavior of the old emitter, we explicitly indent
                // the body of a class with static initializers.
                ts.setEmitFlags(classExpression, 65536 /* Indented */ | ts.getEmitFlags(classExpression));
                expressions.push(ts.startOnNewLine(ts.createAssignment(temp, classExpression)));
                ts.addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
                expressions.push(ts.startOnNewLine(temp));
                return ts.inlineExpressions(expressions);
            }
            return classExpression;
        }
        /**
         * Transforms the members of a class.
         *
         * @param node The current class.
         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
         */
        function transformClassMembers(node, isDerivedClass) {
            var members = [];
            var constructor = transformConstructor(node, isDerivedClass);
            if (constructor) {
                members.push(constructor);
            }
            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
        }
        /**
         * Transforms (or creates) a constructor for a class.
         *
         * @param node The current class.
         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
         */
        function transformConstructor(node, isDerivedClass) {
            // Check if we have property assignment inside class declaration.
            // If there is a 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 = ts.forEach(node.members, isInstanceInitializedProperty);
            var hasParameterPropertyAssignments = node.transformFlags & 262144 /* ContainsParameterPropertyAssignments */;
            var constructor = ts.getFirstConstructorWithBody(node);
            // If the class does not contain nodes that require a synthesized constructor,
            // accept the current constructor if it exists.
            if (!hasInstancePropertyWithInitializer && !hasParameterPropertyAssignments) {
                return ts.visitEachChild(constructor, visitor, context);
            }
            var parameters = transformConstructorParameters(constructor);
            var body = transformConstructorBody(node, constructor, isDerivedClass);
            //  constructor(${parameters}) {
            //      ${body}
            //  }
            return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(ts.createConstructor(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, parameters, body), constructor || node), constructor));
        }
        /**
         * Transforms (or creates) the parameters for the constructor of a class with
         * parameter property assignments or instance property initializers.
         *
         * @param constructor The constructor declaration.
         */
        function transformConstructorParameters(constructor) {
            // The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
            // If constructor is empty, then
            //     If ClassHeritag_eopt is present and protoParent is not null, then
            //          Let constructor be the result of parsing the source text
            //              constructor(...args) { super (...args);}
            //          using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
            //      Else,
            //           Let constructor be the result of parsing the source text
            //               constructor( ){ }
            //           using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
            //
            // While we could emit the '...args' rest parameter, certain later tools in the pipeline might
            // downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
            // Instead, we'll avoid using a rest parameter and spread into the super call as
            // 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody".
            return ts.visitParameterList(constructor && constructor.parameters, visitor, context)
                || [];
        }
        /**
         * Transforms (or creates) a constructor body for a class with parameter property
         * assignments or instance property initializers.
         *
         * @param node The current class.
         * @param constructor The current class constructor.
         * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
         */
        function transformConstructorBody(node, constructor, isDerivedClass) {
            var statements = [];
            var indexOfFirstStatement = 0;
            resumeLexicalEnvironment();
            if (constructor) {
                indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements);
                // Add parameters with property assignments. Transforms this:
                //
                //  constructor (public x, public y) {
                //  }
                //
                // Into this:
                //
                //  constructor (x, y) {
                //      this.x = x;
                //      this.y = y;
                //  }
                //
                var propertyAssignments = getParametersWithPropertyAssignments(constructor);
                ts.addRange(statements, ts.map(propertyAssignments, transformParameterWithPropertyAssignment));
            }
            else if (isDerivedClass) {
                // Add a synthetic `super` call:
                //
                //  super(...arguments);
                //
                statements.push(ts.createStatement(ts.createCall(ts.createSuper(), 
                /*typeArguments*/ undefined, [ts.createSpread(ts.createIdentifier("arguments"))])));
            }
            // Add the property initializers. Transforms this:
            //
            //  public x = 1;
            //
            // Into this:
            //
            //  constructor() {
            //      this.x = 1;
            //  }
            //
            var properties = getInitializedProperties(node, /*isStatic*/ false);
            addInitializedPropertyStatements(statements, properties, ts.createThis());
            if (constructor) {
                // The class already had a constructor, so we should add the existing statements, skipping the initial super call.
                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement));
            }
            // End the lexical environment.
            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            return ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ constructor ? constructor.body.statements : node.members), 
            /*multiLine*/ true), 
            /*location*/ constructor ? constructor.body : undefined);
        }
        /**
         * Adds super call and preceding prologue directives into the list of statements.
         *
         * @param ctor The constructor node.
         * @returns index of the statement that follows super call
         */
        function addPrologueDirectivesAndInitialSuperCall(ctor, result) {
            if (ctor.body) {
                var statements = ctor.body.statements;
                // add prologue directives to the list (if any)
                var index = ts.addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
                if (index === statements.length) {
                    // list contains nothing but prologue directives (or empty) - exit
                    return index;
                }
                var statement = statements[index];
                if (statement.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
                    result.push(ts.visitNode(statement, visitor, ts.isStatement));
                    return index + 1;
                }
                return index;
            }
            return 0;
        }
        /**
         * Gets all parameters of a constructor that should be transformed into property assignments.
         *
         * @param node The constructor node.
         */
        function getParametersWithPropertyAssignments(node) {
            return ts.filter(node.parameters, isParameterWithPropertyAssignment);
        }
        /**
         * Determines whether a parameter should be transformed into a property assignment.
         *
         * @param parameter The parameter node.
         */
        function isParameterWithPropertyAssignment(parameter) {
            return ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */)
                && ts.isIdentifier(parameter.name);
        }
        /**
         * Transforms a parameter into a property assignment statement.
         *
         * @param node The parameter declaration.
         */
        function transformParameterWithPropertyAssignment(node) {
            ts.Debug.assert(ts.isIdentifier(node.name));
            var name = node.name;
            var propertyName = ts.getMutableClone(name);
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 48 /* NoSourceMap */);
            var localName = ts.getMutableClone(name);
            ts.setEmitFlags(localName, 1536 /* NoComments */);
            return ts.startOnNewLine(ts.setTextRange(ts.createStatement(ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createThis(), propertyName), node.name), localName)), ts.moveRangePos(node, -1)));
        }
        /**
         * Gets all property declarations with initializers on either the static or instance side of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to get properties from the static or instance side of the class.
         */
        function getInitializedProperties(node, isStatic) {
            return ts.filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
        }
        /**
         * Gets a value indicating whether a class element is a static property declaration with an initializer.
         *
         * @param member The class element node.
         */
        function isStaticInitializedProperty(member) {
            return isInitializedProperty(member, /*isStatic*/ true);
        }
        /**
         * Gets a value indicating whether a class element is an instance property declaration with an initializer.
         *
         * @param member The class element node.
         */
        function isInstanceInitializedProperty(member) {
            return isInitializedProperty(member, /*isStatic*/ false);
        }
        /**
         * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
         *
         * @param member The class element node.
         * @param isStatic A value indicating whether the member should be a static or instance member.
         */
        function isInitializedProperty(member, isStatic) {
            return member.kind === 149 /* PropertyDeclaration */
                && isStatic === ts.hasModifier(member, 32 /* Static */)
                && member.initializer !== undefined;
        }
        /**
         * Generates assignment statements for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function addInitializedPropertyStatements(statements, properties, receiver) {
            for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) {
                var property = properties_10[_i];
                var statement = ts.createStatement(transformInitializedProperty(property, receiver));
                ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property));
                ts.setCommentRange(statement, property);
                statements.push(statement);
            }
        }
        /**
         * Generates assignment expressions for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function generateInitializedPropertyExpressions(properties, receiver) {
            var expressions = [];
            for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) {
                var property = properties_11[_i];
                var expression = transformInitializedProperty(property, receiver);
                expression.startsOnNewLine = true;
                ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property));
                ts.setCommentRange(expression, property);
                expressions.push(expression);
            }
            return expressions;
        }
        /**
         * Transforms a property initializer into an assignment statement.
         *
         * @param property The property declaration.
         * @param receiver The object receiving the property assignment.
         */
        function transformInitializedProperty(property, receiver) {
            var propertyName = visitPropertyNameOfClassElement(property);
            var initializer = ts.visitNode(property.initializer, visitor, ts.isExpression);
            var memberAccess = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
            return ts.createAssignment(memberAccess, initializer);
        }
        /**
         * Gets either the static or instance members of a class that are decorated, or have
         * parameters that are decorated.
         *
         * @param node The class containing the member.
         * @param isStatic A value indicating whether to retrieve static or instance members of
         *                 the class.
         */
        function getDecoratedClassElements(node, isStatic) {
            return ts.filter(node.members, isStatic ? isStaticDecoratedClassElement : isInstanceDecoratedClassElement);
        }
        /**
         * Determines whether a class member is a static member of a class that is decorated, or
         * has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isStaticDecoratedClassElement(member) {
            return isDecoratedClassElement(member, /*isStatic*/ true);
        }
        /**
         * Determines whether a class member is an instance member of a class that is decorated,
         * or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isInstanceDecoratedClassElement(member) {
            return isDecoratedClassElement(member, /*isStatic*/ false);
        }
        /**
         * Determines whether a class member is either a static or an instance member of a class
         * that is decorated, or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isDecoratedClassElement(member, isStatic) {
            return ts.nodeOrChildIsDecorated(member)
                && isStatic === ts.hasModifier(member, 32 /* Static */);
        }
        /**
         * Gets an array of arrays of decorators for the parameters of a function-like node.
         * The offset into the result array should correspond to the offset of the parameter.
         *
         * @param node The function-like node.
         */
        function getDecoratorsOfParameters(node) {
            var decorators;
            if (node) {
                var parameters = node.parameters;
                for (var i = 0; i < parameters.length; i++) {
                    var parameter = parameters[i];
                    if (decorators || parameter.decorators) {
                        if (!decorators) {
                            decorators = new Array(parameters.length);
                        }
                        decorators[i] = parameter.decorators;
                    }
                }
            }
            return decorators;
        }
        /**
         * Gets an AllDecorators object containing the decorators for the class and the decorators for the
         * parameters of the constructor of the class.
         *
         * @param node The class node.
         */
        function getAllDecoratorsOfConstructor(node) {
            var decorators = node.decorators;
            var parameters = getDecoratorsOfParameters(ts.getFirstConstructorWithBody(node));
            if (!decorators && !parameters) {
                return undefined;
            }
            return {
                decorators: decorators,
                parameters: parameters
            };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the member and its parameters.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function getAllDecoratorsOfClassElement(node, member) {
            switch (member.kind) {
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return getAllDecoratorsOfAccessors(node, member);
                case 151 /* MethodDeclaration */:
                    return getAllDecoratorsOfMethod(member);
                case 149 /* PropertyDeclaration */:
                    return getAllDecoratorsOfProperty(member);
                default:
                    return undefined;
            }
        }
        /**
         * Gets an AllDecorators object containing the decorators for the accessor and its parameters.
         *
         * @param node The class node that contains the accessor.
         * @param accessor The class accessor member.
         */
        function getAllDecoratorsOfAccessors(node, accessor) {
            if (!accessor.body) {
                return undefined;
            }
            var _a = ts.getAllAccessorDeclarations(node.members, accessor), firstAccessor = _a.firstAccessor, secondAccessor = _a.secondAccessor, setAccessor = _a.setAccessor;
            var firstAccessorWithDecorators = firstAccessor.decorators ? firstAccessor : secondAccessor && secondAccessor.decorators ? secondAccessor : undefined;
            if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) {
                return undefined;
            }
            var decorators = firstAccessorWithDecorators.decorators;
            var parameters = getDecoratorsOfParameters(setAccessor);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the method and its parameters.
         *
         * @param method The class method member.
         */
        function getAllDecoratorsOfMethod(method) {
            if (!method.body) {
                return undefined;
            }
            var decorators = method.decorators;
            var parameters = getDecoratorsOfParameters(method);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the property.
         *
         * @param property The class property member.
         */
        function getAllDecoratorsOfProperty(property) {
            var decorators = property.decorators;
            if (!decorators) {
                return undefined;
            }
            return { decorators: decorators };
        }
        /**
         * Transforms all of the decorators for a declaration into an array of expressions.
         *
         * @param node The declaration node.
         * @param allDecorators An object containing all of the decorators for the declaration.
         */
        function transformAllDecoratorsOfDeclaration(node, container, allDecorators) {
            if (!allDecorators) {
                return undefined;
            }
            var decoratorExpressions = [];
            ts.addRange(decoratorExpressions, ts.map(allDecorators.decorators, transformDecorator));
            ts.addRange(decoratorExpressions, ts.flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
            addTypeMetadata(node, container, decoratorExpressions);
            return decoratorExpressions;
        }
        /**
         * Generates statements used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate statements for static or
         *                 instance members.
         */
        function addClassElementDecorationStatements(statements, node, isStatic) {
            ts.addRange(statements, ts.map(generateClassElementDecorationExpressions(node, isStatic), expressionToStatement));
        }
        /**
         * Generates expressions used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate expressions for static or
         *                 instance members.
         */
        function generateClassElementDecorationExpressions(node, isStatic) {
            var members = getDecoratedClassElements(node, isStatic);
            var expressions;
            for (var _i = 0, members_3 = members; _i < members_3.length; _i++) {
                var member = members_3[_i];
                var expression = generateClassElementDecorationExpression(node, member);
                if (expression) {
                    if (!expressions) {
                        expressions = [expression];
                    }
                    else {
                        expressions.push(expression);
                    }
                }
            }
            return expressions;
        }
        /**
         * Generates an expression used to evaluate class element decorators at runtime.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function generateClassElementDecorationExpression(node, member) {
            var allDecorators = getAllDecoratorsOfClassElement(node, member);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            // 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:
            //
            //   __decorate([
            //       dec,
            //       __param(0, dec2),
            //       __metadata("design:type", Function),
            //       __metadata("design:paramtypes", [Object]),
            //       __metadata("design:returntype", void 0)
            //   ], C.prototype, "method", null);
            //
            // The emit for an accessor is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "accessor", null);
            //
            // The emit for a property is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "prop");
            //
            var prefix = getClassMemberPrefix(node, member);
            var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true);
            var descriptor = languageVersion > 0 /* ES3 */
                ? member.kind === 149 /* PropertyDeclaration */
                    // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it
                    // should not invoke `Object.getOwnPropertyDescriptor`.
                    ? ts.createVoidZero()
                    // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly.
                    // We have this extra argument here so that we can inject an explicit property descriptor at a later date.
                    : ts.createNull()
                : undefined;
            var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member));
            ts.setEmitFlags(helper, 1536 /* NoComments */);
            return helper;
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function addConstructorDecorationStatement(statements, node) {
            var expression = generateConstructorDecorationExpression(node);
            if (expression) {
                statements.push(ts.setOriginalNode(ts.createStatement(expression), node));
            }
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function generateConstructorDecorationExpression(node) {
            var allDecorators = getAllDecoratorsOfConstructor(node);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            var classAlias = classAliases && classAliases[ts.getOriginalNodeId(node)];
            var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            var decorate = createDecorateHelper(context, decoratorExpressions, localName);
            var expression = ts.createAssignment(localName, classAlias ? ts.createAssignment(classAlias, decorate) : decorate);
            ts.setEmitFlags(expression, 1536 /* NoComments */);
            ts.setSourceMapRange(expression, ts.moveRangePastDecorators(node));
            return expression;
        }
        /**
         * Transforms a decorator into an expression.
         *
         * @param decorator The decorator node.
         */
        function transformDecorator(decorator) {
            return ts.visitNode(decorator.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the decorators of a parameter.
         *
         * @param decorators The decorators for the parameter at the provided offset.
         * @param parameterOffset The offset of the parameter.
         */
        function transformDecoratorsOfParameter(decorators, parameterOffset) {
            var expressions;
            if (decorators) {
                expressions = [];
                for (var _i = 0, decorators_1 = decorators; _i < decorators_1.length; _i++) {
                    var decorator = decorators_1[_i];
                    var helper = createParamHelper(context, transformDecorator(decorator), parameterOffset, 
                    /*location*/ decorator.expression);
                    ts.setEmitFlags(helper, 1536 /* NoComments */);
                    expressions.push(helper);
                }
            }
            return expressions;
        }
        /**
         * Adds optional type metadata for a declaration.
         *
         * @param node The declaration node.
         * @param decoratorExpressions The destination array to which to add new decorator expressions.
         */
        function addTypeMetadata(node, container, decoratorExpressions) {
            if (USE_NEW_TYPE_METADATA_FORMAT) {
                addNewTypeMetadata(node, container, decoratorExpressions);
            }
            else {
                addOldTypeMetadata(node, container, decoratorExpressions);
            }
        }
        function addOldTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                if (shouldAddTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container)));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
                }
            }
        }
        function addNewTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                var properties = void 0;
                if (shouldAddTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("type", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeTypeOfNode(node))));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("paramTypes", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeParameterTypesOfNode(node, container))));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("returnType", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeReturnTypeOfNode(node))));
                }
                if (properties) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", ts.createObjectLiteral(properties, /*multiLine*/ true)));
                }
            }
        }
        /**
         * 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.
         *
         * @param node The node to test.
         */
        function shouldAddTypeMetadata(node) {
            var kind = node.kind;
            return kind === 151 /* MethodDeclaration */
                || kind === 153 /* GetAccessor */
                || kind === 154 /* SetAccessor */
                || kind === 149 /* PropertyDeclaration */;
        }
        /**
         * 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.
         *
         * @param node The node to test.
         */
        function shouldAddReturnTypeMetadata(node) {
            return node.kind === 151 /* MethodDeclaration */;
        }
        /**
         * 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.
         *
         * @param node The node to test.
         */
        function shouldAddParamTypesMetadata(node) {
            switch (node.kind) {
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                    return ts.getFirstConstructorWithBody(node) !== undefined;
                case 151 /* MethodDeclaration */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return true;
            }
            return false;
        }
        /**
         * Serializes the type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its type serialized.
         */
        function serializeTypeOfNode(node) {
            switch (node.kind) {
                case 149 /* PropertyDeclaration */:
                case 146 /* Parameter */:
                case 153 /* GetAccessor */:
                    return serializeTypeNode(node.type);
                case 154 /* SetAccessor */:
                    return serializeTypeNode(ts.getSetAccessorTypeAnnotationNode(node));
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                case 151 /* MethodDeclaration */:
                    return ts.createIdentifier("Function");
                default:
                    return ts.createVoidZero();
            }
        }
        /**
         * Serializes the types of the parameters of a node for use with decorator type metadata.
         *
         * @param node The node that should have its parameter types serialized.
         */
        function serializeParameterTypesOfNode(node, container) {
            var valueDeclaration = ts.isClassLike(node)
                ? ts.getFirstConstructorWithBody(node)
                : ts.isFunctionLike(node) && ts.nodeIsPresent(node.body)
                    ? node
                    : undefined;
            var expressions = [];
            if (valueDeclaration) {
                var parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
                var numParameters = parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i];
                    if (i === 0 && ts.isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
                        continue;
                    }
                    if (parameter.dotDotDotToken) {
                        expressions.push(serializeTypeNode(ts.getRestParameterElementType(parameter.type)));
                    }
                    else {
                        expressions.push(serializeTypeOfNode(parameter));
                    }
                }
            }
            return ts.createArrayLiteral(expressions);
        }
        function getParametersOfDecoratedDeclaration(node, container) {
            if (container && node.kind === 153 /* GetAccessor */) {
                var setAccessor = ts.getAllAccessorDeclarations(container.members, node).setAccessor;
                if (setAccessor) {
                    return setAccessor.parameters;
                }
            }
            return node.parameters;
        }
        /**
         * Serializes the return type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its return type serialized.
         */
        function serializeReturnTypeOfNode(node) {
            if (ts.isFunctionLike(node) && node.type) {
                return serializeTypeNode(node.type);
            }
            else if (ts.isAsyncFunction(node)) {
                return ts.createIdentifier("Promise");
            }
            return ts.createVoidZero();
        }
        /**
         * Serializes a type node for use with decorator type metadata.
         *
         * Types are serialized in the following fashion:
         * - Void types point to "undefined" (e.g. "void 0")
         * - Function and Constructor types point to the global "Function" constructor.
         * - Interface types with a call or construct signature types point to the global
         *   "Function" constructor.
         * - Array and Tuple types point to the global "Array" constructor.
         * - Type predicates and booleans point to the global "Boolean" constructor.
         * - String literal types and strings point to the global "String" constructor.
         * - Enum and number types point to the global "Number" constructor.
         * - Symbol types point to the global "Symbol" constructor.
         * - Type references to classes (or class-like variables) point to the constructor for the class.
         * - Anything else points to the global "Object" constructor.
         *
         * @param node The type node to serialize.
         */
        function serializeTypeNode(node) {
            if (node === undefined) {
                return ts.createIdentifier("Object");
            }
            switch (node.kind) {
                case 105 /* VoidKeyword */:
                case 139 /* UndefinedKeyword */:
                case 95 /* NullKeyword */:
                case 130 /* NeverKeyword */:
                    return ts.createVoidZero();
                case 168 /* ParenthesizedType */:
                    return serializeTypeNode(node.type);
                case 160 /* FunctionType */:
                case 161 /* ConstructorType */:
                    return ts.createIdentifier("Function");
                case 164 /* ArrayType */:
                case 165 /* TupleType */:
                    return ts.createIdentifier("Array");
                case 158 /* TypePredicate */:
                case 122 /* BooleanKeyword */:
                    return ts.createIdentifier("Boolean");
                case 136 /* StringKeyword */:
                    return ts.createIdentifier("String");
                case 134 /* ObjectKeyword */:
                    return ts.createIdentifier("Object");
                case 173 /* LiteralType */:
                    switch (node.literal.kind) {
                        case 9 /* StringLiteral */:
                            return ts.createIdentifier("String");
                        case 8 /* NumericLiteral */:
                            return ts.createIdentifier("Number");
                        case 101 /* TrueKeyword */:
                        case 86 /* FalseKeyword */:
                            return ts.createIdentifier("Boolean");
                        default:
                            ts.Debug.failBadSyntaxKind(node.literal);
                            break;
                    }
                    break;
                case 133 /* NumberKeyword */:
                    return ts.createIdentifier("Number");
                case 137 /* SymbolKeyword */:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case 159 /* TypeReference */:
                    return serializeTypeReferenceNode(node);
                case 167 /* IntersectionType */:
                case 166 /* UnionType */:
                    return serializeUnionOrIntersectionType(node);
                case 162 /* TypeQuery */:
                case 170 /* TypeOperator */:
                case 171 /* IndexedAccessType */:
                case 172 /* MappedType */:
                case 163 /* TypeLiteral */:
                case 119 /* AnyKeyword */:
                case 169 /* ThisType */:
                    break;
                default:
                    ts.Debug.failBadSyntaxKind(node);
                    break;
            }
            return ts.createIdentifier("Object");
        }
        function serializeUnionOrIntersectionType(node) {
            // Note when updating logic here also update getEntityNameForDecoratorMetadata
            // so that aliases can be marked as referenced
            var serializedUnion;
            for (var _i = 0, _a = node.types; _i < _a.length; _i++) {
                var typeNode = _a[_i];
                while (typeNode.kind === 168 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 130 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 95 /* NullKeyword */ || typeNode.kind === 139 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var serializedIndividual = serializeTypeNode(typeNode);
                if (ts.isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
                    // One of the individual is global object, return immediately
                    return serializedIndividual;
                }
                else if (serializedUnion) {
                    // Different types
                    if (!ts.isIdentifier(serializedUnion) ||
                        !ts.isIdentifier(serializedIndividual) ||
                        serializedUnion.escapedText !== serializedIndividual.escapedText) {
                        return ts.createIdentifier("Object");
                    }
                }
                else {
                    // Initialize the union type
                    serializedUnion = serializedIndividual;
                }
            }
            // If we were able to find common type, use it
            return serializedUnion || ts.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never
        }
        /**
         * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with
         * decorator type metadata.
         *
         * @param node The type reference node.
         */
        function serializeTypeReferenceNode(node) {
            switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) {
                case ts.TypeReferenceSerializationKind.Unknown:
                    var serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true);
                    var temp = ts.createTempVariable(hoistVariableDeclaration);
                    return ts.createLogicalOr(ts.createLogicalAnd(ts.createTypeCheck(ts.createAssignment(temp, serialized), "function"), temp), ts.createIdentifier("Object"));
                case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
                    return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false);
                case ts.TypeReferenceSerializationKind.VoidNullableOrNeverType:
                    return ts.createVoidZero();
                case ts.TypeReferenceSerializationKind.BooleanType:
                    return ts.createIdentifier("Boolean");
                case ts.TypeReferenceSerializationKind.NumberLikeType:
                    return ts.createIdentifier("Number");
                case ts.TypeReferenceSerializationKind.StringLikeType:
                    return ts.createIdentifier("String");
                case ts.TypeReferenceSerializationKind.ArrayLikeType:
                    return ts.createIdentifier("Array");
                case ts.TypeReferenceSerializationKind.ESSymbolType:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case ts.TypeReferenceSerializationKind.TypeWithCallSignature:
                    return ts.createIdentifier("Function");
                case ts.TypeReferenceSerializationKind.Promise:
                    return ts.createIdentifier("Promise");
                case ts.TypeReferenceSerializationKind.ObjectType:
                default:
                    return ts.createIdentifier("Object");
            }
        }
        /**
         * Serializes an entity name as an expression for decorator type metadata.
         *
         * @param node The entity name to serialize.
         * @param useFallback A value indicating whether to use logical operators to test for the
         *                    entity name at runtime.
         */
        function serializeEntityNameAsExpression(node, useFallback) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    // Create a clone of the name with a new parent, and treat it as if it were
                    // a source tree node for the purposes of the checker.
                    var name = ts.getMutableClone(node);
                    name.flags &= ~8 /* Synthesized */;
                    name.original = undefined;
                    name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
                    if (useFallback) {
                        return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name);
                    }
                    return name;
                case 143 /* QualifiedName */:
                    return serializeQualifiedNameAsExpression(node, useFallback);
            }
        }
        /**
         * Serializes an qualified name as an expression for decorator type metadata.
         *
         * @param node The qualified name to serialize.
         * @param useFallback A value indicating whether to use logical operators to test for the
         *                    qualified name at runtime.
         */
        function serializeQualifiedNameAsExpression(node, useFallback) {
            var left;
            if (node.left.kind === 71 /* Identifier */) {
                left = serializeEntityNameAsExpression(node.left, useFallback);
            }
            else if (useFallback) {
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                left = ts.createLogicalAnd(ts.createAssignment(temp, serializeEntityNameAsExpression(node.left, /*useFallback*/ true)), temp);
            }
            else {
                left = serializeEntityNameAsExpression(node.left, /*useFallback*/ false);
            }
            return ts.createPropertyAccess(left, node.right);
        }
        /**
         * Gets an expression that points to the global "Symbol" constructor at runtime if it is
         * available.
         */
        function getGlobalSymbolNameWithFallback() {
            return ts.createConditional(ts.createTypeCheck(ts.createIdentifier("Symbol"), "function"), ts.createIdentifier("Symbol"), ts.createIdentifier("Object"));
        }
        /**
         * Gets an expression that represents a property name. For a computed property, a
         * name is generated for the node.
         *
         * @param member The member whose name should be converted into an expression.
         */
        function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
            var name = member.name;
            if (ts.isComputedPropertyName(name)) {
                return generateNameForComputedPropertyName
                    ? ts.getGeneratedNameForNode(name)
                    : name.expression;
            }
            else if (ts.isIdentifier(name)) {
                return ts.createLiteral(ts.idText(name));
            }
            else {
                return ts.getSynthesizedClone(name);
            }
        }
        /**
         * Visits the property name of a class element, for use when emitting property
         * initializers. For a computed property on a node with decorators, a temporary
         * value is stored for later use.
         *
         * @param member The member whose name should be visited.
         */
        function visitPropertyNameOfClassElement(member) {
            var name = member.name;
            if (ts.isComputedPropertyName(name)) {
                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
                if (member.decorators) {
                    var generatedName = ts.getGeneratedNameForNode(name);
                    hoistVariableDeclaration(generatedName);
                    expression = ts.createAssignment(generatedName, expression);
                }
                return ts.updateComputedPropertyName(name, expression);
            }
            else {
                return name;
            }
        }
        /**
         * Transforms a HeritageClause with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node is a non-`extends` heritage clause that should be elided.
         * - The node is an `extends` heritage clause that should be visited, but only allow a single type.
         *
         * @param node The HeritageClause to transform.
         */
        function visitHeritageClause(node) {
            if (node.token === 85 /* ExtendsKeyword */) {
                var types = ts.visitNodes(node.types, visitor, ts.isExpressionWithTypeArguments, 0, 1);
                return ts.setTextRange(ts.createHeritageClause(85 /* ExtendsKeyword */, types), node);
            }
            return undefined;
        }
        /**
         * Transforms an ExpressionWithTypeArguments with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node contains type arguments that should be elided.
         *
         * @param node The ExpressionWithTypeArguments to transform.
         */
        function visitExpressionWithTypeArguments(node) {
            return ts.updateExpressionWithTypeArguments(node, 
            /*typeArguments*/ undefined, ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
        }
        /**
         * Determines whether to emit a function-like declaration. We should not emit the
         * declaration if it does not have a body.
         *
         * @param node The declaration node.
         */
        function shouldEmitFunctionLikeDeclaration(node) {
            return !ts.nodeIsMissing(node.body);
        }
        function visitConstructor(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            return ts.updateConstructor(node, ts.visitNodes(node.decorators, visitor, ts.isDecorator), ts.visitNodes(node.modifiers, visitor, ts.isModifier), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a method declaration of a class.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is an overload
         * - The node is marked as abstract, public, private, protected, or readonly
         * - The node has both a decorator and a computed property name
         *
         * @param node The method node.
         */
        function visitMethodDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        /**
         * Determines whether to emit an accessor declaration. We should not emit the
         * declaration if it does not have a body and is abstract.
         *
         * @param node The declaration node.
         */
        function shouldEmitAccessorDeclaration(node) {
            return !(ts.nodeIsMissing(node.body) && ts.hasModifier(node, 128 /* Abstract */));
        }
        /**
         * Visits a get accessor declaration of a class.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked as abstract, public, private, or protected
         * - The node has both a decorator and a computed property name
         *
         * @param node The get accessor node.
         */
        function visitGetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        /**
         * Visits a set accessor declaration of a class.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked as abstract, public, private, or protected
         * - The node has both a decorator and a computed property name
         *
         * @param node The set accessor node.
         */
        function visitSetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        /**
         * Visits a function declaration.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is an overload
         * - The node is exported from a TypeScript namespace
         * - The node has decorators
         *
         * @param node The function node.
         */
        function visitFunctionDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (isExportOfNamespace(node)) {
                var statements = [updated];
                addExportMemberAssignment(statements, node);
                return statements;
            }
            return updated;
        }
        /**
         * Visits a function expression node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node has type annotations
         *
         * @param node The function expression node.
         */
        function visitFunctionExpression(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createOmittedExpression();
            }
            var updated = ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            return updated;
        }
        /**
         * @remarks
         * This function will be called when one of the following conditions are met:
         * - The node has type annotations
         */
        function visitArrowFunction(node) {
            var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context));
            return updated;
        }
        /**
         * Visits a parameter declaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node has an accessibility modifier.
         * - The node has a questionToken.
         * - The node's kind is ThisKeyword.
         *
         * @param node The parameter declaration node.
         */
        function visitParameter(node) {
            if (ts.parameterIsThisKeyword(node)) {
                return undefined;
            }
            var parameter = ts.createParameter(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, node.dotDotDotToken, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*questionToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            // While we emit the source map for the node after skipping decorators and modifiers,
            // we need to emit the comments for the original range.
            ts.setOriginalNode(parameter, node);
            ts.setTextRange(parameter, ts.moveRangePastModifiers(node));
            ts.setCommentRange(parameter, node);
            ts.setSourceMapRange(parameter, ts.moveRangePastModifiers(node));
            ts.setEmitFlags(parameter.name, 32 /* NoTrailingSourceMap */);
            return parameter;
        }
        /**
         * Visits a variable statement in a namespace.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is exported from a TypeScript namespace.
         */
        function visitVariableStatement(node) {
            if (isExportOfNamespace(node)) {
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    // elide statement if there are no initialized variables.
                    return undefined;
                }
                return ts.setTextRange(ts.createStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformInitializedVariable(node) {
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, 
                /*needsValue*/ false, createNamespaceExportExpression);
            }
            else {
                return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), ts.visitNode(node.initializer, visitor, ts.isExpression)), 
                /*location*/ node);
            }
        }
        function visitVariableDeclaration(node) {
            return ts.updateVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
        }
        /**
         * Visits a parenthesized expression that contains either a type assertion or an `as`
         * expression.
         *
         * @param node The parenthesized expression node.
         */
        function visitParenthesizedExpression(node) {
            var innerExpression = ts.skipOuterExpressions(node.expression, ~2 /* Assertions */);
            if (ts.isAssertionExpression(innerExpression)) {
                // Make sure we consider all nested cast expressions, e.g.:
                // (<any><number><any>-A).x;
                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                // We have an expression of the form: (<Type>SubExpr). Emitting this as (SubExpr)
                // is really not desirable. We would like to emit the subexpression 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.
                //
                // To preserve comments, we return a "PartiallyEmittedExpression" here which will
                // preserve the position information of the original expression.
                //
                // Due to the auto-parenthesization rules used by the visitor and factory functions
                // we can safely elide the parentheses here, as a new synthetic
                // ParenthesizedExpression will be inserted if we remove parentheses too
                // aggressively.
                return ts.createPartiallyEmittedExpression(expression, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitAssertionExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitNonNullExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitCallExpression(node) {
            return ts.updateCall(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitNewExpression(node) {
            return ts.updateNew(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        /**
         * Determines whether to emit an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function shouldEmitEnumDeclaration(node) {
            return !ts.isConst(node)
                || compilerOptions.preserveConstEnums
                || compilerOptions.isolatedModules;
        }
        /**
         * Visits an enum declaration.
         *
         * This function will be called any time a TypeScript enum is encountered.
         *
         * @param node The enum declaration node.
         */
        function visitEnumDeclaration(node) {
            if (!shouldEmitEnumDeclaration(node)) {
                return undefined;
            }
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the enum. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // enum body.
            if (addVarForEnumOrModuleDeclaration(statements, node)) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the enum.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the enum for assignments.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x) {
            //      x[x["y"] = 0] = "y";
            //      ...
            //  })(x || (x = {}));
            var enumStatement = ts.createStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformEnumBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(enumStatement, node);
            ts.setTextRange(enumStatement, node);
            ts.setEmitFlags(enumStatement, emitFlags);
            statements.push(enumStatement);
            // Add a DeclarationMarker for the enum to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function transformEnumBody(node, localName) {
            var savedCurrentNamespaceLocalName = currentNamespaceContainerName;
            currentNamespaceContainerName = localName;
            var statements = [];
            startLexicalEnvironment();
            ts.addRange(statements, ts.map(node.members, transformEnumMember));
            ts.addRange(statements, endLexicalEnvironment());
            currentNamespaceContainerName = savedCurrentNamespaceLocalName;
            return ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), 
            /*multiLine*/ true);
        }
        /**
         * Transforms an enum member into a statement.
         *
         * @param member The enum member node.
         */
        function transformEnumMember(member) {
            // enums don't support computed properties
            // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
            // old emitter always generate 'expression' part of the name as-is.
            var name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
            var valueExpression = transformEnumMemberDeclarationValue(member);
            var innerAssignment = ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, name), valueExpression);
            var outerAssignment = valueExpression.kind === 9 /* StringLiteral */ ?
                innerAssignment :
                ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, innerAssignment), name);
            return ts.setTextRange(ts.createStatement(ts.setTextRange(outerAssignment, member)), member);
        }
        /**
         * Transforms the value of an enum member.
         *
         * @param member The enum member node.
         */
        function transformEnumMemberDeclarationValue(member) {
            var value = resolver.getConstantValue(member);
            if (value !== undefined) {
                return ts.createLiteral(value);
            }
            else {
                enableSubstitutionForNonQualifiedEnumMembers();
                if (member.initializer) {
                    return ts.visitNode(member.initializer, visitor, ts.isExpression);
                }
                else {
                    return ts.createVoidZero();
                }
            }
        }
        /**
         * Determines whether to elide a module declaration.
         *
         * @param node The module declaration node.
         */
        function shouldEmitModuleDeclaration(node) {
            return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules);
        }
        /**
         * Determines whether an exported declaration will have a qualified export name (e.g. `f.x`
         * or `exports.x`).
         */
        function hasNamespaceQualifiedExportName(node) {
            return isExportOfNamespace(node)
                || (isExternalModuleExport(node)
                    && moduleKind !== ts.ModuleKind.ES2015
                    && moduleKind !== ts.ModuleKind.ESNext
                    && moduleKind !== ts.ModuleKind.System);
        }
        /**
         * Records that a declaration was emitted in the current scope, if it was the first
         * declaration for the provided symbol.
         */
        function recordEmittedDeclarationInScope(node) {
            if (!currentScopeFirstDeclarationsOfName) {
                currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap();
            }
            var name = declaredNameInScope(node);
            if (!currentScopeFirstDeclarationsOfName.has(name)) {
                currentScopeFirstDeclarationsOfName.set(name, node);
            }
        }
        /**
         * Determines whether a declaration is the first declaration with
         * the same name emitted in the current scope.
         */
        function isFirstEmittedDeclarationInScope(node) {
            if (currentScopeFirstDeclarationsOfName) {
                var name = declaredNameInScope(node);
                return currentScopeFirstDeclarationsOfName.get(name) === node;
            }
            return true;
        }
        function declaredNameInScope(node) {
            ts.Debug.assertNode(node.name, ts.isIdentifier);
            return node.name.escapedText;
        }
        /**
         * Adds a leading VariableStatement for a enum or module declaration.
         */
        function addVarForEnumOrModuleDeclaration(statements, node) {
            // Emit a variable statement for the module. We emit top-level enums as a `var`
            // declaration to avoid static errors in global scripts scripts due to redeclaration.
            // enums in any other scope are emitted as a `let` declaration.
            var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))
            ], currentScope.kind === 265 /* SourceFile */ ? 0 /* None */ : 1 /* Let */));
            ts.setOriginalNode(statement, node);
            recordEmittedDeclarationInScope(node);
            if (isFirstEmittedDeclarationInScope(node)) {
                // Adjust the source map emit to match the old emitter.
                if (node.kind === 232 /* EnumDeclaration */) {
                    ts.setSourceMapRange(statement.declarationList, node);
                }
                else {
                    ts.setSourceMapRange(statement, node);
                }
                // Trailing comments for module declaration should be emitted after the function closure
                // instead of the variable statement:
                //
                //     /** Module comment*/
                //     module m1 {
                //         function foo4Export() {
                //         }
                //     } // trailing comment module
                //
                // Should emit:
                //
                //     /** Module comment*/
                //     var m1;
                //     (function (m1) {
                //         function foo4Export() {
                //         }
                //     })(m1 || (m1 = {})); // trailing comment module
                //
                ts.setCommentRange(statement, node);
                ts.setEmitFlags(statement, 1024 /* NoTrailingComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(statement);
                return true;
            }
            else {
                // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
                // declaration we do not emit a leading variable declaration. To preserve the
                // begin/end semantics of the declararation and to properly handle exports
                // we wrap the leading variable declaration in a `MergeDeclarationMarker`.
                var mergeMarker = ts.createMergeDeclarationMarker(statement);
                ts.setEmitFlags(mergeMarker, 1536 /* NoComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(mergeMarker);
                return false;
            }
        }
        /**
         * Visits a module declaration node.
         *
         * This function will be called any time a TypeScript namespace (ModuleDeclaration) is encountered.
         *
         * @param node The module declaration node.
         */
        function visitModuleDeclaration(node) {
            if (!shouldEmitModuleDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name.");
            enableSubstitutionForNamespaceExports();
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the module. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // module body.
            if (addVarForEnumOrModuleDeclaration(statements, node)) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the namespace.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the namespace for exports.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x_1) {
            //      x_1.y = ...;
            //  })(x || (x = {}));
            var moduleStatement = ts.createStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformModuleBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(moduleStatement, node);
            ts.setTextRange(moduleStatement, node);
            ts.setEmitFlags(moduleStatement, emitFlags);
            statements.push(moduleStatement);
            // Add a DeclarationMarker for the namespace to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of a module declaration.
         *
         * @param node The module declaration node.
         */
        function transformModuleBody(node, namespaceLocalName) {
            var savedCurrentNamespaceContainerName = currentNamespaceContainerName;
            var savedCurrentNamespace = currentNamespace;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            currentNamespaceContainerName = namespaceLocalName;
            currentNamespace = node;
            currentScopeFirstDeclarationsOfName = undefined;
            var statements = [];
            startLexicalEnvironment();
            var statementsLocation;
            var blockLocation;
            var body = node.body;
            if (body.kind === 234 /* ModuleBlock */) {
                saveStateAndInvoke(body, function (body) { return ts.addRange(statements, ts.visitNodes(body.statements, namespaceElementVisitor, ts.isStatement)); });
                statementsLocation = body.statements;
                blockLocation = body;
            }
            else {
                var result = visitModuleDeclaration(body);
                if (result) {
                    if (ts.isArray(result)) {
                        ts.addRange(statements, result);
                    }
                    else {
                        statements.push(result);
                    }
                }
                var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
                statementsLocation = ts.moveRangePos(moduleBlock.statements, -1);
            }
            ts.addRange(statements, endLexicalEnvironment());
            currentNamespaceContainerName = savedCurrentNamespaceContainerName;
            currentNamespace = savedCurrentNamespace;
            currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ statementsLocation), 
            /*multiLine*/ true);
            ts.setTextRange(block, blockLocation);
            // namespace hello.hi.world {
            //      function foo() {}
            //
            //      // TODO, blah
            // }
            //
            // should be emitted as
            //
            // var hello;
            // (function (hello) {
            //     var hi;
            //     (function (hi) {
            //         var world;
            //         (function (world) {
            //             function foo() { }
            //             // TODO, blah
            //         })(world = hi.world || (hi.world = {}));
            //     })(hi = hello.hi || (hello.hi = {}));
            // })(hello || (hello = {}));
            // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
            if (body.kind !== 234 /* ModuleBlock */) {
                ts.setEmitFlags(block, ts.getEmitFlags(block) | 1536 /* NoComments */);
            }
            return block;
        }
        function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
            if (moduleDeclaration.body.kind === 233 /* ModuleDeclaration */) {
                var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
                return recursiveInnerModule || moduleDeclaration.body;
            }
        }
        /**
         * Visits an import declaration, eliding it if it is not referenced.
         *
         * @param node The import declaration node.
         */
        function visitImportDeclaration(node) {
            if (!node.importClause) {
                // Do not elide a side-effect only import declaration.
                //  import "foo";
                return node;
            }
            // Elide the declaration if the import clause was elided.
            var importClause = ts.visitNode(node.importClause, visitImportClause, ts.isImportClause);
            return importClause
                ? ts.updateImportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, importClause, node.moduleSpecifier)
                : undefined;
        }
        /**
         * Visits an import clause, eliding it if it is not referenced.
         *
         * @param node The import clause node.
         */
        function visitImportClause(node) {
            // Elide the import clause if we elide both its name and its named bindings.
            var name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
            var namedBindings = ts.visitNode(node.namedBindings, visitNamedImportBindings, ts.isNamedImportBindings);
            return (name || namedBindings) ? ts.updateImportClause(node, name, namedBindings) : undefined;
        }
        /**
         * Visits named import bindings, eliding it if it is not referenced.
         *
         * @param node The named import bindings node.
         */
        function visitNamedImportBindings(node) {
            if (node.kind === 240 /* NamespaceImport */) {
                // Elide a namespace import if it is not referenced.
                return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
            }
            else {
                // Elide named imports if all of its import specifiers are elided.
                var elements = ts.visitNodes(node.elements, visitImportSpecifier, ts.isImportSpecifier);
                return ts.some(elements) ? ts.updateNamedImports(node, elements) : undefined;
            }
        }
        /**
         * Visits an import specifier, eliding it if it is not referenced.
         *
         * @param node The import specifier node.
         */
        function visitImportSpecifier(node) {
            // Elide an import specifier if it is not referenced.
            return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Visits an export assignment, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export assignment node.
         */
        function visitExportAssignment(node) {
            // Elide the export assignment if it does not reference a value.
            return resolver.isValueAliasDeclaration(node)
                ? ts.visitEachChild(node, visitor, context)
                : undefined;
        }
        /**
         * Visits an export declaration, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export declaration node.
         */
        function visitExportDeclaration(node) {
            if (!node.exportClause) {
                // Elide a star export if the module it references does not export a value.
                return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
            }
            if (!resolver.isValueAliasDeclaration(node)) {
                // Elide the export declaration if it does not export a value.
                return undefined;
            }
            // Elide the export declaration if all of its named exports are elided.
            var exportClause = ts.visitNode(node.exportClause, visitNamedExports, ts.isNamedExports);
            return exportClause
                ? ts.updateExportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, exportClause, node.moduleSpecifier)
                : undefined;
        }
        /**
         * Visits named exports, eliding it if it does not contain an export specifier that
         * resolves to a value.
         *
         * @param node The named exports node.
         */
        function visitNamedExports(node) {
            // Elide the named exports if all of its export specifiers were elided.
            var elements = ts.visitNodes(node.elements, visitExportSpecifier, ts.isExportSpecifier);
            return ts.some(elements) ? ts.updateNamedExports(node, elements) : undefined;
        }
        /**
         * Visits an export specifier, eliding it if it does not resolve to a value.
         *
         * @param node The export specifier node.
         */
        function visitExportSpecifier(node) {
            // Elide an export specifier if it does not reference a value.
            return resolver.isValueAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Determines whether to emit an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function shouldEmitImportEqualsDeclaration(node) {
            // 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
            return resolver.isReferencedAliasDeclaration(node)
                || (!ts.isExternalModule(currentSourceFile)
                    && resolver.isTopLevelValueImportEqualsWithEntityName(node));
        }
        /**
         * Visits an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function visitImportEqualsDeclaration(node) {
            if (ts.isExternalModuleImportEqualsDeclaration(node)) {
                // Elide external module `import=` if it is not referenced.
                return resolver.isReferencedAliasDeclaration(node)
                    ? ts.visitEachChild(node, visitor, context)
                    : undefined;
            }
            if (!shouldEmitImportEqualsDeclaration(node)) {
                return undefined;
            }
            var moduleReference = ts.createExpressionFromEntityName(node.moduleReference);
            ts.setEmitFlags(moduleReference, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
            if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) {
                //  export var ${name} = ${moduleReference};
                //  var ${name} = ${moduleReference};
                return ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.createVariableDeclaration(node.name, 
                    /*type*/ undefined, moduleReference), node)
                ])), node), node);
            }
            else {
                // exports.${name} = ${moduleReference};
                return ts.setOriginalNode(createNamespaceExport(node.name, moduleReference, node), node);
            }
        }
        /**
         * Gets a value indicating whether the node is exported from a namespace.
         *
         * @param node The node to test.
         */
        function isExportOfNamespace(node) {
            return currentNamespace !== undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is exported from an external module.
         *
         * @param node The node to test.
         */
        function isExternalModuleExport(node) {
            return currentNamespace === undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is a named export from an external module.
         *
         * @param node The node to test.
         */
        function isNamedExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && !ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Gets a value indicating whether the node is the default export of an external module.
         *
         * @param node The node to test.
         */
        function isDefaultExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Creates a statement for the provided expression. This is used in calls to `map`.
         */
        function expressionToStatement(expression) {
            return ts.createStatement(expression);
        }
        function addExportMemberAssignment(statements, node) {
            var expression = ts.createAssignment(ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), ts.getLocalName(node));
            ts.setSourceMapRange(expression, ts.createRange(node.name ? node.name.pos : node.pos, node.end));
            var statement = ts.createStatement(expression);
            ts.setSourceMapRange(statement, ts.createRange(-1, node.end));
            statements.push(statement);
        }
        function createNamespaceExport(exportName, exportValue, location) {
            return ts.setTextRange(ts.createStatement(ts.createAssignment(ts.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue)), location);
        }
        function createNamespaceExportExpression(exportName, exportValue, location) {
            return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
        }
        function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) {
            return ts.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true);
        }
        /**
         * Gets the declaration name used inside of a namespace or enum.
         */
        function getNamespaceParameterName(node) {
            var name = ts.getGeneratedNameForNode(node);
            ts.setSourceMapRange(name, node.name);
            return name;
        }
        /**
         * Gets the expression used to refer to a namespace or enum within the body
         * of its declaration.
         */
        function getNamespaceContainerName(node) {
            return ts.getGeneratedNameForNode(node);
        }
        /**
         * Gets a local alias for a class declaration if it is a decorated class with an internal
         * reference to the static side of the class. This is necessary to avoid issues with
         * double-binding semantics for the class name.
         */
        function getClassAliasIfNeeded(node) {
            if (resolver.getNodeCheckFlags(node) & 8388608 /* ClassWithConstructorReference */) {
                enableSubstitutionForClassAliases();
                var classAlias = ts.createUniqueName(node.name && !ts.isGeneratedIdentifier(node.name) ? ts.idText(node.name) : "default");
                classAliases[ts.getOriginalNodeId(node)] = classAlias;
                hoistVariableDeclaration(classAlias);
                return classAlias;
            }
        }
        function getClassPrototype(node) {
            return ts.createPropertyAccess(ts.getDeclarationName(node), "prototype");
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getDeclarationName(node)
                : getClassPrototype(node);
        }
        function enableSubstitutionForNonQualifiedEnumMembers() {
            if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) {
                enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */;
                context.enableSubstitution(71 /* Identifier */);
            }
        }
        function enableSubstitutionForClassAliases() {
            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
                enabledSubstitutions |= 1 /* ClassAliases */;
                // We need to enable substitutions for identifiers. This allows us to
                // substitute class names inside of a class declaration.
                context.enableSubstitution(71 /* Identifier */);
                // Keep track of class aliases.
                classAliases = [];
            }
        }
        function enableSubstitutionForNamespaceExports() {
            if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) {
                enabledSubstitutions |= 2 /* NamespaceExports */;
                // We need to enable substitutions for identifiers and shorthand property assignments. This allows us to
                // substitute the names of exported members of a namespace.
                context.enableSubstitution(71 /* Identifier */);
                context.enableSubstitution(262 /* ShorthandPropertyAssignment */);
                // We need to be notified when entering and exiting namespaces.
                context.enableEmitNotification(233 /* ModuleDeclaration */);
            }
        }
        function isTransformedModuleDeclaration(node) {
            return ts.getOriginalNode(node).kind === 233 /* ModuleDeclaration */;
        }
        function isTransformedEnumDeclaration(node) {
            return ts.getOriginalNode(node).kind === 232 /* EnumDeclaration */;
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            var savedApplicableSubstitutions = applicableSubstitutions;
            var savedCurrentSourceFile = currentSourceFile;
            if (ts.isSourceFile(node)) {
                currentSourceFile = node;
            }
            if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) {
                applicableSubstitutions |= 2 /* NamespaceExports */;
            }
            if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) {
                applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */;
            }
            previousOnEmitNode(hint, node, emitCallback);
            applicableSubstitutions = savedApplicableSubstitutions;
            currentSourceFile = savedCurrentSourceFile;
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        function substituteShorthandPropertyAssignment(node) {
            if (enabledSubstitutions & 2 /* NamespaceExports */) {
                var name = node.name;
                var exportedName = trySubstituteNamespaceExportedName(name);
                if (exportedName) {
                    // A shorthand property with an assignment initializer is probably part of a
                    // destructuring assignment
                    if (node.objectAssignmentInitializer) {
                        var initializer = ts.createAssignment(exportedName, node.objectAssignmentInitializer);
                        return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                    }
                    return ts.setTextRange(ts.createPropertyAssignment(name, exportedName), node);
                }
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 179 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 180 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            return trySubstituteClassAlias(node)
                || trySubstituteNamespaceExportedName(node)
                || node;
        }
        function trySubstituteClassAlias(node) {
            if (enabledSubstitutions & 1 /* ClassAliases */) {
                if (resolver.getNodeCheckFlags(node) & 16777216 /* ConstructorReferenceInClass */) {
                    // Due to the emit for class decorators, any reference to the class from inside of the class body
                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                    // behavior of class names in ES6.
                    // Also, when emitting statics for class expressions, we must substitute a class alias for
                    // constructor references in static property initializers.
                    var declaration = resolver.getReferencedValueDeclaration(node);
                    if (declaration) {
                        var classAlias = classAliases[declaration.id];
                        if (classAlias) {
                            var clone_1 = ts.getSynthesizedClone(classAlias);
                            ts.setSourceMapRange(clone_1, node);
                            ts.setCommentRange(clone_1, node);
                            return clone_1;
                        }
                    }
                }
            }
            return undefined;
        }
        function trySubstituteNamespaceExportedName(node) {
            // If this is explicitly a local name, do not substitute.
            if (enabledSubstitutions & applicableSubstitutions && !ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                // If we are nested within a namespace declaration, we may need to qualifiy
                // an identifier that is exported from a merged namespace.
                var container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
                if (container && container.kind !== 265 /* SourceFile */) {
                    var substitute = (applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 233 /* ModuleDeclaration */) ||
                        (applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 232 /* EnumDeclaration */);
                    if (substitute) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(container), node), 
                        /*location*/ node);
                    }
                }
            }
            return undefined;
        }
        function substitutePropertyAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteElementAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteConstantValue(node) {
            var constantValue = tryGetConstEnumValue(node);
            if (constantValue !== undefined) {
                // track the constant value on the node for the printer in needsDotDotForPropertyAccess
                ts.setConstantValue(node, constantValue);
                var substitute = ts.createLiteral(constantValue);
                if (!compilerOptions.removeComments) {
                    var propertyName = ts.isPropertyAccessExpression(node)
                        ? ts.declarationNameToString(node.name)
                        : ts.getTextOfNode(node.argumentExpression);
                    ts.addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, " " + propertyName + " ");
                }
                return substitute;
            }
            return node;
        }
        function tryGetConstEnumValue(node) {
            if (compilerOptions.isolatedModules) {
                return undefined;
            }
            return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)
                ? resolver.getConstantValue(node)
                : undefined;
        }
    }
    ts.transformTypeScript = transformTypeScript;
    function createDecorateHelper(context, decoratorExpressions, target, memberName, descriptor, location) {
        var argumentsArray = [];
        argumentsArray.push(ts.createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
        argumentsArray.push(target);
        if (memberName) {
            argumentsArray.push(memberName);
            if (descriptor) {
                argumentsArray.push(descriptor);
            }
        }
        context.requestEmitHelper(decorateHelper);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__decorate"), 
        /*typeArguments*/ undefined, argumentsArray), location);
    }
    var decorateHelper = {
        name: "typescript:decorate",
        scoped: false,
        priority: 2,
        text: "\n            var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n                var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n                if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n                else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n                return c > 3 && r && Object.defineProperty(target, key, r), r;\n            };"
    };
    function createMetadataHelper(context, metadataKey, metadataValue) {
        context.requestEmitHelper(metadataHelper);
        return ts.createCall(ts.getHelperName("__metadata"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(metadataKey),
            metadataValue
        ]);
    }
    var metadataHelper = {
        name: "typescript:metadata",
        scoped: false,
        priority: 3,
        text: "\n            var __metadata = (this && this.__metadata) || function (k, v) {\n                if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n            };"
    };
    function createParamHelper(context, expression, parameterOffset, location) {
        context.requestEmitHelper(paramHelper);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__param"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(parameterOffset),
            expression
        ]), location);
    }
    var paramHelper = {
        name: "typescript:param",
        scoped: false,
        priority: 4,
        text: "\n            var __param = (this && this.__param) || function (paramIndex, decorator) {\n                return function (target, key) { decorator(target, key, paramIndex); }\n            };"
    };
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
var ts;
(function (ts) {
    var ES2017SubstitutionFlags;
    (function (ES2017SubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ES2017SubstitutionFlags[ES2017SubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ES2017SubstitutionFlags || (ES2017SubstitutionFlags = {}));
    function transformES2017(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * This keeps track of containers where `super` is valid, for use with
         * just-in-time substitution for `super` expressions inside of async methods.
         */
        var enclosingSuperContainerFlags = 0;
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        return transformSourceFile;
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if ((node.transformFlags & 16 /* ContainsES2017 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 120 /* AsyncKeyword */:
                    // ES2017 async modifier should be elided for targets < ES2017
                    return undefined;
                case 191 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 151 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 186 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 187 /* ArrowFunction */:
                    return visitArrowFunction(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        /**
         * Visits an AwaitExpression node.
         *
         * This function will be called any time a ES2017 await expression is encountered.
         *
         * @param node The node to visit.
         */
        function visitAwaitExpression(node) {
            return ts.setOriginalNode(ts.setTextRange(ts.createYield(
            /*asteriskToken*/ undefined, ts.visitNode(node.expression, visitor, ts.isExpression)), node), node);
        }
        /**
         * Visits a MethodDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked as async
         *
         * @param node The node to visit.
         */
        function visitMethodDeclaration(node) {
            return ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionExpression node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            return ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits an ArrowFunction.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitArrowFunction(node) {
            return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        function transformAsyncFunctionBody(node) {
            resumeLexicalEnvironment();
            var original = ts.getOriginalNode(node, ts.isFunctionLike);
            var nodeType = original.type;
            var promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : undefined;
            var isArrowFunction = node.kind === 187 /* ArrowFunction */;
            var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 8192 /* CaptureArguments */) !== 0;
            // An async function is emit as an outer function that calls an inner
            // generator function. To preserve lexical bindings, we pass the current
            // `this` and `arguments` objects to `__awaiter`. The generator function
            // passed to `__awaiter` is executed inside of the callback to the
            // promise constructor.
            if (!isArrowFunction) {
                var statements = [];
                var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
                statements.push(ts.createReturn(createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body, statementOffset))));
                ts.addRange(statements, endLexicalEnvironment());
                var block = ts.createBlock(statements, /*multiLine*/ true);
                ts.setTextRange(block, node.body);
                // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
                // This step isn't needed if we eventually transform this to ES5.
                if (languageVersion >= 2 /* ES2015 */) {
                    if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                        enableSubstitutionForAsyncMethodsWithSuper();
                        ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                    }
                    else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                        enableSubstitutionForAsyncMethodsWithSuper();
                        ts.addEmitHelper(block, ts.asyncSuperHelper);
                    }
                }
                return block;
            }
            else {
                var expression = createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body));
                var declarations = endLexicalEnvironment();
                if (ts.some(declarations)) {
                    var block = ts.convertToFunctionBody(expression);
                    return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(ts.concatenate(block.statements, declarations)), block.statements));
                }
                return expression;
            }
        }
        function transformFunctionBodyWorker(body, start) {
            if (ts.isBlock(body)) {
                return ts.updateBlock(body, ts.visitLexicalEnvironment(body.statements, visitor, context, start));
            }
            else {
                startLexicalEnvironment();
                var visited = ts.convertToFunctionBody(ts.visitNode(body, visitor, ts.isConciseBody));
                var declarations = endLexicalEnvironment();
                return ts.updateBlock(visited, ts.setTextRange(ts.createNodeArray(ts.concatenate(visited.statements, declarations)), visited.statements));
            }
        }
        function getPromiseConstructor(type) {
            var typeName = type && ts.getEntityNameFromTypeNode(type);
            if (typeName && ts.isEntityName(typeName)) {
                var serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
                if (serializationKind === ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
                    || serializationKind === ts.TypeReferenceSerializationKind.Unknown) {
                    return typeName;
                }
            }
            return undefined;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(181 /* CallExpression */);
                context.enableSubstitution(179 /* PropertyAccessExpression */);
                context.enableSubstitution(180 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(229 /* ClassDeclaration */);
                context.enableEmitNotification(151 /* MethodDeclaration */);
                context.enableEmitNotification(153 /* GetAccessor */);
                context.enableEmitNotification(154 /* SetAccessor */);
                context.enableEmitNotification(152 /* Constructor */);
            }
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 179 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 180 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 181 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 97 /* SuperKeyword */) {
                return createSuperAccessInAsyncMethod(ts.createLiteral(ts.idText(node.name)), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 97 /* SuperKeyword */) {
                return createSuperAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, [
                    ts.createThis()
                ].concat(node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 229 /* ClassDeclaration */
                || kind === 152 /* Constructor */
                || kind === 151 /* MethodDeclaration */
                || kind === 153 /* GetAccessor */
                || kind === 154 /* SetAccessor */;
        }
        function createSuperAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_super"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createIdentifier("_super"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2017 = transformES2017;
    var awaiterHelper = {
        name: "typescript:awaiter",
        scoped: false,
        priority: 5,
        text: "\n            var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n                return new (P || (P = Promise))(function (resolve, reject) {\n                    function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n                    function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n                    function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n                    step((generator = generator.apply(thisArg, _arguments || [])).next());\n                });\n            };"
    };
    function createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, body) {
        context.requestEmitHelper(awaiterHelper);
        var generatorFunc = ts.createFunctionExpression(
        /*modifiers*/ undefined, ts.createToken(39 /* AsteriskToken */), 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ [], 
        /*type*/ undefined, body);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
        return ts.createCall(ts.getHelperName("__awaiter"), 
        /*typeArguments*/ undefined, [
            ts.createThis(),
            hasLexicalArguments ? ts.createIdentifier("arguments") : ts.createVoidZero(),
            promiseConstructor ? ts.createExpressionFromEntityName(promiseConstructor) : ts.createVoidZero(),
            generatorFunc
        ]);
    }
    ts.asyncSuperHelper = {
        name: "typescript:async-super",
        scoped: true,
        text: "\n            const _super = name => super[name];\n        "
    };
    ts.advancedAsyncSuperHelper = {
        name: "typescript:advanced-async-super",
        scoped: true,
        text: "\n            const _super = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);\n        "
    };
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/// <reference path="es2017.ts" />
/*@internal*/
var ts;
(function (ts) {
    var ESNextSubstitutionFlags;
    (function (ESNextSubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ESNextSubstitutionFlags[ESNextSubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ESNextSubstitutionFlags || (ESNextSubstitutionFlags = {}));
    function transformESNext(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var enabledSubstitutions;
        var enclosingFunctionFlags;
        var enclosingSuperContainerFlags = 0;
        return transformSourceFile;
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            return visitorWorker(node, /*noDestructuringValue*/ false);
        }
        function visitorNoDestructuringValue(node) {
            return visitorWorker(node, /*noDestructuringValue*/ true);
        }
        function visitorNoAsyncModifier(node) {
            if (node.kind === 120 /* AsyncKeyword */) {
                return undefined;
            }
            return node;
        }
        function visitorWorker(node, noDestructuringValue) {
            if ((node.transformFlags & 8 /* ContainsESNext */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 191 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 197 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 222 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 178 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 194 /* BinaryExpression */:
                    return visitBinaryExpression(node, noDestructuringValue);
                case 226 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 216 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 214 /* ForStatement */:
                    return visitForStatement(node);
                case 190 /* VoidExpression */:
                    return visitVoidExpression(node);
                case 152 /* Constructor */:
                    return visitConstructorDeclaration(node);
                case 151 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 153 /* GetAccessor */:
                    return visitGetAccessorDeclaration(node);
                case 154 /* SetAccessor */:
                    return visitSetAccessorDeclaration(node);
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 186 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 187 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 146 /* Parameter */:
                    return visitParameter(node);
                case 210 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 185 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, noDestructuringValue);
                case 260 /* CatchClause */:
                    return visitCatchClause(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitAwaitExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.visitNode(node.expression, visitor, ts.isExpression))), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitYieldExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ && node.asteriskToken) {
                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.updateYield(node, node.asteriskToken, createAsyncDelegatorHelper(context, createAsyncValuesHelper(context, expression, expression), expression)))), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLabeledStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                var statement = ts.unwrapInnermostStatementOfLabel(node);
                if (statement.kind === 216 /* ForOfStatement */ && statement.awaitModifier) {
                    return visitForOfStatement(statement, node);
                }
                return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function chunkObjectLiteralElements(elements) {
            var chunkObject;
            var objects = [];
            for (var _i = 0, elements_3 = elements; _i < elements_3.length; _i++) {
                var e = elements_3[_i];
                if (e.kind === 263 /* SpreadAssignment */) {
                    if (chunkObject) {
                        objects.push(ts.createObjectLiteral(chunkObject));
                        chunkObject = undefined;
                    }
                    var target = e.expression;
                    objects.push(ts.visitNode(target, visitor, ts.isExpression));
                }
                else {
                    if (!chunkObject) {
                        chunkObject = [];
                    }
                    if (e.kind === 261 /* PropertyAssignment */) {
                        var p = e;
                        chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression)));
                    }
                    else {
                        chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                    }
                }
            }
            if (chunkObject) {
                objects.push(ts.createObjectLiteral(chunkObject));
            }
            return objects;
        }
        function visitObjectLiteralExpression(node) {
            if (node.transformFlags & 1048576 /* ContainsObjectSpread */) {
                // spread elements emit like so:
                // non-spread elements are chunked together into object literals, and then all are passed to __assign:
                //     { a, ...o, b } => __assign({a}, o, {b});
                // If the first element is a spread element, then the first argument to __assign is {}:
                //     { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
                var objects = chunkObjectLiteralElements(node.properties);
                if (objects.length && objects[0].kind !== 178 /* ObjectLiteralExpression */) {
                    objects.unshift(ts.createObjectLiteral());
                }
                return createAssignHelper(context, objects);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitExpressionStatement(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        function visitParenthesizedExpression(node, noDestructuringValue) {
            return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
        }
        function visitCatchClause(node) {
            if (!node.variableDeclaration) {
                return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         */
        function visitBinaryExpression(node, noDestructuringValue) {
            if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 1048576 /* ContainsObjectRest */) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 1 /* ObjectRest */, !noDestructuringValue);
            }
            else if (node.operatorToken.kind === 26 /* CommaToken */) {
                return ts.updateBinary(node, ts.visitNode(node.left, visitorNoDestructuringValue, ts.isExpression), ts.visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            // If we are here it is because the name contains a binding pattern with a rest somewhere in it.
            if (ts.isBindingPattern(node.name) && node.name.transformFlags & 1048576 /* ContainsObjectRest */) {
                return ts.flattenDestructuringBinding(node, visitor, context, 1 /* ObjectRest */);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForStatement(node) {
            return ts.updateFor(node, ts.visitNode(node.initializer, visitorNoDestructuringValue, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement));
        }
        function visitVoidExpression(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        /**
         * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
         *
         * @param node A ForOfStatement.
         */
        function visitForOfStatement(node, outermostLabeledStatement) {
            if (node.initializer.transformFlags & 1048576 /* ContainsObjectRest */) {
                node = transformForOfStatementWithObjectRest(node);
            }
            if (node.awaitModifier) {
                return transformForAwaitOfStatement(node, outermostLabeledStatement);
            }
            else {
                return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement);
            }
        }
        function transformForOfStatementWithObjectRest(node) {
            var initializerWithoutParens = ts.skipParentheses(node.initializer);
            if (ts.isVariableDeclarationList(initializerWithoutParens) || ts.isAssignmentPattern(initializerWithoutParens)) {
                var bodyLocation = void 0;
                var statementsLocation = void 0;
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var statements = [ts.createForOfBindingStatement(initializerWithoutParens, temp)];
                if (ts.isBlock(node.statement)) {
                    ts.addRange(statements, node.statement.statements);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement.statements;
                }
                return ts.updateForOf(node, node.awaitModifier, ts.setTextRange(ts.createVariableDeclarationList([
                    ts.setTextRange(ts.createVariableDeclaration(temp), node.initializer)
                ], 1 /* Let */), node.initializer), node.expression, ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
                /*multiLine*/ true), bodyLocation));
            }
            return node;
        }
        function convertForOfStatementHead(node, boundValue) {
            var binding = ts.createForOfBindingStatement(node.initializer, boundValue);
            var bodyLocation;
            var statementsLocation;
            var statements = [ts.visitNode(binding, visitor, ts.isStatement)];
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement);
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
                bodyLocation = statement;
                statementsLocation = statement.statements;
            }
            else {
                statements.push(statement);
            }
            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function createDownlevelAwait(expression) {
            return enclosingFunctionFlags & 1 /* Generator */
                ? ts.createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression))
                : ts.createAwait(expression);
        }
        function transformForAwaitOfStatement(node, outermostLabeledStatement) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
            var callNext = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            var getDone = ts.createPropertyAccess(result, "done");
            var getValue = ts.createPropertyAccess(result, "value");
            var callReturn = ts.createFunctionCall(returnMethod, iterator, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, callValues), node.expression),
                ts.createVariableDeclaration(result)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createComma(ts.createAssignment(result, createDownlevelAwait(callNext)), ts.createLogicalNot(getDone)), 
            /*incrementor*/ undefined, 
            /*statement*/ convertForOfStatementHead(node, createDownlevelAwait(getValue))), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(getDone)), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createStatement(createDownlevelAwait(callReturn))), 1 /* SingleLine */)
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        function visitParameter(node) {
            if (node.transformFlags & 1048576 /* ContainsObjectRest */) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.updateParameter(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, node.dotDotDotToken, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitConstructorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateConstructor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitGetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitSetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitMethodDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitNode(/*questionToken*/ undefined, visitor, ts.isToken), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitArrowFunction(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateArrowFunction(node, node.modifiers, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionExpression(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionExpression(node, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function transformAsyncGeneratorFunctionBody(node) {
            resumeLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
            appendObjectRestAssignmentsIfNeeded(statements, node);
            statements.push(ts.createReturn(createAsyncGeneratorHelper(context, ts.createFunctionExpression(
            /*modifiers*/ undefined, ts.createToken(39 /* AsteriskToken */), node.name && ts.getGeneratedNameForNode(node.name), 
            /*typeParameters*/ undefined, 
            /*parameters*/ [], 
            /*type*/ undefined, ts.updateBlock(node.body, ts.visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset))))));
            ts.addRange(statements, endLexicalEnvironment());
            var block = ts.updateBlock(node.body, statements);
            // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
            // This step isn't needed if we eventually transform this to ES5.
            if (languageVersion >= 2 /* ES2015 */) {
                if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                    enableSubstitutionForAsyncMethodsWithSuper();
                    ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                }
                else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                    enableSubstitutionForAsyncMethodsWithSuper();
                    ts.addEmitHelper(block, ts.asyncSuperHelper);
                }
            }
            return block;
        }
        function transformFunctionBody(node) {
            resumeLexicalEnvironment();
            var statementOffset = 0;
            var statements = [];
            var body = ts.visitNode(node.body, visitor, ts.isConciseBody);
            if (ts.isBlock(body)) {
                statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            }
            ts.addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
            var trailingStatements = endLexicalEnvironment();
            if (statementOffset > 0 || ts.some(statements) || ts.some(trailingStatements)) {
                var block = ts.convertToFunctionBody(body, /*multiLine*/ true);
                ts.addRange(statements, block.statements.slice(statementOffset));
                ts.addRange(statements, trailingStatements);
                return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(statements), block.statements));
            }
            return body;
        }
        function appendObjectRestAssignmentsIfNeeded(statements, node) {
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                if (parameter.transformFlags & 1048576 /* ContainsObjectRest */) {
                    var temp = ts.getGeneratedNameForNode(parameter);
                    var declarations = ts.flattenDestructuringBinding(parameter, visitor, context, 1 /* ObjectRest */, temp, 
                    /*doNotRecordTempVariablesInLine*/ false, 
                    /*skipInitializer*/ true);
                    if (ts.some(declarations)) {
                        var statement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList(declarations));
                        ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                        statements = ts.append(statements, statement);
                    }
                }
            }
            return statements;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(181 /* CallExpression */);
                context.enableSubstitution(179 /* PropertyAccessExpression */);
                context.enableSubstitution(180 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(229 /* ClassDeclaration */);
                context.enableEmitNotification(151 /* MethodDeclaration */);
                context.enableEmitNotification(153 /* GetAccessor */);
                context.enableEmitNotification(154 /* SetAccessor */);
                context.enableEmitNotification(152 /* Constructor */);
            }
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 179 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 180 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 181 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 97 /* SuperKeyword */) {
                return createSuperAccessInAsyncMethod(ts.createLiteral(ts.idText(node.name)), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 97 /* SuperKeyword */) {
                return createSuperAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, [
                    ts.createThis()
                ].concat(node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 229 /* ClassDeclaration */
                || kind === 152 /* Constructor */
                || kind === 151 /* MethodDeclaration */
                || kind === 153 /* GetAccessor */
                || kind === 154 /* SetAccessor */;
        }
        function createSuperAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_super"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createIdentifier("_super"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformESNext = transformESNext;
    var assignHelper = {
        name: "typescript:assign",
        scoped: false,
        priority: 1,
        text: "\n            var __assign = (this && this.__assign) || Object.assign || function(t) {\n                for (var s, i = 1, n = arguments.length; i < n; i++) {\n                    s = arguments[i];\n                    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n                        t[p] = s[p];\n                }\n                return t;\n            };"
    };
    function createAssignHelper(context, attributesSegments) {
        if (context.getCompilerOptions().target >= 2 /* ES2015 */) {
            return ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "assign"), 
            /*typeArguments*/ undefined, attributesSegments);
        }
        context.requestEmitHelper(assignHelper);
        return ts.createCall(ts.getHelperName("__assign"), 
        /*typeArguments*/ undefined, attributesSegments);
    }
    ts.createAssignHelper = createAssignHelper;
    var awaitHelper = {
        name: "typescript:await",
        scoped: false,
        text: "\n            var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }\n        "
    };
    function createAwaitHelper(context, expression) {
        context.requestEmitHelper(awaitHelper);
        return ts.createCall(ts.getHelperName("__await"), /*typeArguments*/ undefined, [expression]);
    }
    var asyncGeneratorHelper = {
        name: "typescript:asyncGenerator",
        scoped: false,
        text: "\n            var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var g = generator.apply(thisArg, _arguments || []), i, q = [];\n                return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n                function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n                function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n                function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);  }\n                function fulfill(value) { resume(\"next\", value); }\n                function reject(value) { resume(\"throw\", value); }\n                function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n            };\n        "
    };
    function createAsyncGeneratorHelper(context, generatorFunc) {
        context.requestEmitHelper(awaitHelper);
        context.requestEmitHelper(asyncGeneratorHelper);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */;
        return ts.createCall(ts.getHelperName("__asyncGenerator"), 
        /*typeArguments*/ undefined, [
            ts.createThis(),
            ts.createIdentifier("arguments"),
            generatorFunc
        ]);
    }
    var asyncDelegator = {
        name: "typescript:asyncDelegator",
        scoped: false,
        text: "\n            var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {\n                var i, p;\n                return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n                function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; }; }\n            };\n        "
    };
    function createAsyncDelegatorHelper(context, expression, location) {
        context.requestEmitHelper(awaitHelper);
        context.requestEmitHelper(asyncDelegator);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncDelegator"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    var asyncValues = {
        name: "typescript:asyncValues",
        scoped: false,
        text: "\n            var __asyncValues = (this && this.__asyncIterator) || function (o) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var m = o[Symbol.asyncIterator];\n                return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\n            };\n        "
    };
    function createAsyncValuesHelper(context, expression, location) {
        context.requestEmitHelper(asyncValues);
        return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncValues"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/// <reference path="./esnext.ts" />
/*@internal*/
var ts;
(function (ts) {
    function transformJsx(context) {
        var compilerOptions = context.getCompilerOptions();
        return transformSourceFile;
        /**
         * Transform JSX-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if (node.transformFlags & 4 /* ContainsJsx */) {
                return visitorWorker(node);
            }
            else {
                return node;
            }
        }
        function visitorWorker(node) {
            switch (node.kind) {
                case 249 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ false);
                case 250 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ false);
                case 256 /* JsxExpression */:
                    return visitJsxExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformJsxChildToExpression(node) {
            switch (node.kind) {
                case 10 /* JsxText */:
                    return visitJsxText(node);
                case 256 /* JsxExpression */:
                    return visitJsxExpression(node);
                case 249 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ true);
                case 250 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ true);
                default:
                    ts.Debug.failBadSyntaxKind(node);
                    return undefined;
            }
        }
        function visitJsxElement(node, isChild) {
            return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node);
        }
        function visitJsxSelfClosingElement(node, isChild) {
            return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
        }
        function visitJsxOpeningLikeElement(node, children, isChild, location) {
            var tagName = getTagName(node);
            var objectProperties;
            var attrs = node.attributes.properties;
            if (attrs.length === 0) {
                // When there are no attributes, React wants "null"
                objectProperties = ts.createNull();
            }
            else {
                // Map spans of JsxAttribute nodes into object literals and spans
                // of JsxSpreadAttribute nodes into expressions.
                var segments = ts.flatten(ts.spanMap(attrs, ts.isJsxSpreadAttribute, function (attrs, isSpread) { return isSpread
                    ? ts.map(attrs, transformJsxSpreadAttributeToExpression)
                    : ts.createObjectLiteral(ts.map(attrs, transformJsxAttributeToObjectLiteralElement)); }));
                if (ts.isJsxSpreadAttribute(attrs[0])) {
                    // We must always emit at least one object literal before a spread
                    // argument.
                    segments.unshift(ts.createObjectLiteral());
                }
                // Either emit one big object literal (no spread attribs), or
                // a call to the __assign helper.
                objectProperties = ts.singleOrUndefined(segments);
                if (!objectProperties) {
                    objectProperties = ts.createAssignHelper(context, segments);
                }
            }
            var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function transformJsxSpreadAttributeToExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        function transformJsxAttributeToObjectLiteralElement(node) {
            var name = getAttributeName(node);
            var expression = transformJsxAttributeInitializer(node.initializer);
            return ts.createPropertyAssignment(name, expression);
        }
        function transformJsxAttributeInitializer(node) {
            if (node === undefined) {
                return ts.createTrue();
            }
            else if (node.kind === 9 /* StringLiteral */) {
                var decoded = tryDecodeEntities(node.text);
                return decoded ? ts.setTextRange(ts.createLiteral(decoded), node) : node;
            }
            else if (node.kind === 256 /* JsxExpression */) {
                if (node.expression === undefined) {
                    return ts.createTrue();
                }
                return visitJsxExpression(node);
            }
            else {
                ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxText(node) {
            var fixed = fixupWhitespaceAndDecodeEntities(ts.getTextOfNode(node, /*includeTrivia*/ true));
            return fixed === undefined ? undefined : ts.createLiteral(fixed);
        }
        /**
         * JSX trims whitespace at the end and beginning of lines, except that the
         * start/end of a tag is considered a start/end of a line only if that line is
         * on the same line as the closing tag. See examples in
         * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
         * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model
         *
         * An equivalent algorithm would be:
         * - If there is only one line, return it.
         * - If there is only whitespace (but multiple lines), return `undefined`.
         * - Split the text into lines.
         * - 'trimRight' the first line, 'trimLeft' the last line, 'trim' middle lines.
         * - Decode entities on each line (individually).
         * - Remove empty lines and join the rest with " ".
         */
        function fixupWhitespaceAndDecodeEntities(text) {
            var acc;
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            // Last non-whitespace character on this line.
            var lastNonWhitespace = -1;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitsepace,
            // but lastNonWhitespace = -1 as a special flag to indicate that we *don't* include the line if it's all whitespace.
            for (var i = 0; i < text.length; i++) {
                var c = text.charCodeAt(i);
                if (ts.isLineBreak(c)) {
                    // If we've seen any non-whitespace characters on this line, add the 'trim' of the line.
                    // (lastNonWhitespace === -1 is a special flag to detect whether the first line is all whitespace.)
                    if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) {
                        acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
                    }
                    // Reset firstNonWhitespace for the next line.
                    // Don't bother to reset lastNonWhitespace because we ignore it if firstNonWhitespace = -1.
                    firstNonWhitespace = -1;
                }
                else if (!ts.isWhiteSpaceSingleLine(c)) {
                    lastNonWhitespace = i;
                    if (firstNonWhitespace === -1) {
                        firstNonWhitespace = i;
                    }
                }
            }
            return firstNonWhitespace !== -1
                // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace.
                ? addLineOfJsxText(acc, text.substr(firstNonWhitespace))
                // Last line was all whitespace, so ignore it
                : acc;
        }
        function addLineOfJsxText(acc, trimmedLine) {
            // We do not escape the string here as that is handled by the printer
            // when it emits the literal. We do, however, need to decode JSX entities.
            var decoded = decodeEntities(trimmedLine);
            return acc === undefined ? decoded : acc + " " + decoded;
        }
        /**
         * Replace entities like "&nbsp;", "&#123;", and "&#xDEADBEEF;" with the characters they encode.
         * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
         */
        function decodeEntities(text) {
            return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, function (match, _all, _number, _digits, decimal, hex, word) {
                if (decimal) {
                    return String.fromCharCode(parseInt(decimal, 10));
                }
                else if (hex) {
                    return String.fromCharCode(parseInt(hex, 16));
                }
                else {
                    var ch = entities.get(word);
                    // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
                    return ch ? String.fromCharCode(ch) : match;
                }
            });
        }
        /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */
        function tryDecodeEntities(text) {
            var decoded = decodeEntities(text);
            return decoded === text ? undefined : decoded;
        }
        function getTagName(node) {
            if (node.kind === 249 /* JsxElement */) {
                return getTagName(node.openingElement);
            }
            else {
                var name = node.tagName;
                if (ts.isIdentifier(name) && ts.isIntrinsicJsxName(name.escapedText)) {
                    return ts.createLiteral(ts.idText(name));
                }
                else {
                    return ts.createExpressionFromEntityName(name);
                }
            }
        }
        /**
         * Emit an attribute name, which is quoted if it needs to be quoted. Because
         * these emit into an object literal property name, we don't need to be worried
         * about keywords, just non-identifier characters
         */
        function getAttributeName(node) {
            var name = node.name;
            var text = ts.idText(name);
            if (/^[A-Za-z_]\w*$/.test(text)) {
                return name;
            }
            else {
                return ts.createLiteral(text);
            }
        }
        function visitJsxExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
    }
    ts.transformJsx = transformJsx;
    var entities = ts.createMapFromTemplate({
        "quot": 0x0022,
        "amp": 0x0026,
        "apos": 0x0027,
        "lt": 0x003C,
        "gt": 0x003E,
        "nbsp": 0x00A0,
        "iexcl": 0x00A1,
        "cent": 0x00A2,
        "pound": 0x00A3,
        "curren": 0x00A4,
        "yen": 0x00A5,
        "brvbar": 0x00A6,
        "sect": 0x00A7,
        "uml": 0x00A8,
        "copy": 0x00A9,
        "ordf": 0x00AA,
        "laquo": 0x00AB,
        "not": 0x00AC,
        "shy": 0x00AD,
        "reg": 0x00AE,
        "macr": 0x00AF,
        "deg": 0x00B0,
        "plusmn": 0x00B1,
        "sup2": 0x00B2,
        "sup3": 0x00B3,
        "acute": 0x00B4,
        "micro": 0x00B5,
        "para": 0x00B6,
        "middot": 0x00B7,
        "cedil": 0x00B8,
        "sup1": 0x00B9,
        "ordm": 0x00BA,
        "raquo": 0x00BB,
        "frac14": 0x00BC,
        "frac12": 0x00BD,
        "frac34": 0x00BE,
        "iquest": 0x00BF,
        "Agrave": 0x00C0,
        "Aacute": 0x00C1,
        "Acirc": 0x00C2,
        "Atilde": 0x00C3,
        "Auml": 0x00C4,
        "Aring": 0x00C5,
        "AElig": 0x00C6,
        "Ccedil": 0x00C7,
        "Egrave": 0x00C8,
        "Eacute": 0x00C9,
        "Ecirc": 0x00CA,
        "Euml": 0x00CB,
        "Igrave": 0x00CC,
        "Iacute": 0x00CD,
        "Icirc": 0x00CE,
        "Iuml": 0x00CF,
        "ETH": 0x00D0,
        "Ntilde": 0x00D1,
        "Ograve": 0x00D2,
        "Oacute": 0x00D3,
        "Ocirc": 0x00D4,
        "Otilde": 0x00D5,
        "Ouml": 0x00D6,
        "times": 0x00D7,
        "Oslash": 0x00D8,
        "Ugrave": 0x00D9,
        "Uacute": 0x00DA,
        "Ucirc": 0x00DB,
        "Uuml": 0x00DC,
        "Yacute": 0x00DD,
        "THORN": 0x00DE,
        "szlig": 0x00DF,
        "agrave": 0x00E0,
        "aacute": 0x00E1,
        "acirc": 0x00E2,
        "atilde": 0x00E3,
        "auml": 0x00E4,
        "aring": 0x00E5,
        "aelig": 0x00E6,
        "ccedil": 0x00E7,
        "egrave": 0x00E8,
        "eacute": 0x00E9,
        "ecirc": 0x00EA,
        "euml": 0x00EB,
        "igrave": 0x00EC,
        "iacute": 0x00ED,
        "icirc": 0x00EE,
        "iuml": 0x00EF,
        "eth": 0x00F0,
        "ntilde": 0x00F1,
        "ograve": 0x00F2,
        "oacute": 0x00F3,
        "ocirc": 0x00F4,
        "otilde": 0x00F5,
        "ouml": 0x00F6,
        "divide": 0x00F7,
        "oslash": 0x00F8,
        "ugrave": 0x00F9,
        "uacute": 0x00FA,
        "ucirc": 0x00FB,
        "uuml": 0x00FC,
        "yacute": 0x00FD,
        "thorn": 0x00FE,
        "yuml": 0x00FF,
        "OElig": 0x0152,
        "oelig": 0x0153,
        "Scaron": 0x0160,
        "scaron": 0x0161,
        "Yuml": 0x0178,
        "fnof": 0x0192,
        "circ": 0x02C6,
        "tilde": 0x02DC,
        "Alpha": 0x0391,
        "Beta": 0x0392,
        "Gamma": 0x0393,
        "Delta": 0x0394,
        "Epsilon": 0x0395,
        "Zeta": 0x0396,
        "Eta": 0x0397,
        "Theta": 0x0398,
        "Iota": 0x0399,
        "Kappa": 0x039A,
        "Lambda": 0x039B,
        "Mu": 0x039C,
        "Nu": 0x039D,
        "Xi": 0x039E,
        "Omicron": 0x039F,
        "Pi": 0x03A0,
        "Rho": 0x03A1,
        "Sigma": 0x03A3,
        "Tau": 0x03A4,
        "Upsilon": 0x03A5,
        "Phi": 0x03A6,
        "Chi": 0x03A7,
        "Psi": 0x03A8,
        "Omega": 0x03A9,
        "alpha": 0x03B1,
        "beta": 0x03B2,
        "gamma": 0x03B3,
        "delta": 0x03B4,
        "epsilon": 0x03B5,
        "zeta": 0x03B6,
        "eta": 0x03B7,
        "theta": 0x03B8,
        "iota": 0x03B9,
        "kappa": 0x03BA,
        "lambda": 0x03BB,
        "mu": 0x03BC,
        "nu": 0x03BD,
        "xi": 0x03BE,
        "omicron": 0x03BF,
        "pi": 0x03C0,
        "rho": 0x03C1,
        "sigmaf": 0x03C2,
        "sigma": 0x03C3,
        "tau": 0x03C4,
        "upsilon": 0x03C5,
        "phi": 0x03C6,
        "chi": 0x03C7,
        "psi": 0x03C8,
        "omega": 0x03C9,
        "thetasym": 0x03D1,
        "upsih": 0x03D2,
        "piv": 0x03D6,
        "ensp": 0x2002,
        "emsp": 0x2003,
        "thinsp": 0x2009,
        "zwnj": 0x200C,
        "zwj": 0x200D,
        "lrm": 0x200E,
        "rlm": 0x200F,
        "ndash": 0x2013,
        "mdash": 0x2014,
        "lsquo": 0x2018,
        "rsquo": 0x2019,
        "sbquo": 0x201A,
        "ldquo": 0x201C,
        "rdquo": 0x201D,
        "bdquo": 0x201E,
        "dagger": 0x2020,
        "Dagger": 0x2021,
        "bull": 0x2022,
        "hellip": 0x2026,
        "permil": 0x2030,
        "prime": 0x2032,
        "Prime": 0x2033,
        "lsaquo": 0x2039,
        "rsaquo": 0x203A,
        "oline": 0x203E,
        "frasl": 0x2044,
        "euro": 0x20AC,
        "image": 0x2111,
        "weierp": 0x2118,
        "real": 0x211C,
        "trade": 0x2122,
        "alefsym": 0x2135,
        "larr": 0x2190,
        "uarr": 0x2191,
        "rarr": 0x2192,
        "darr": 0x2193,
        "harr": 0x2194,
        "crarr": 0x21B5,
        "lArr": 0x21D0,
        "uArr": 0x21D1,
        "rArr": 0x21D2,
        "dArr": 0x21D3,
        "hArr": 0x21D4,
        "forall": 0x2200,
        "part": 0x2202,
        "exist": 0x2203,
        "empty": 0x2205,
        "nabla": 0x2207,
        "isin": 0x2208,
        "notin": 0x2209,
        "ni": 0x220B,
        "prod": 0x220F,
        "sum": 0x2211,
        "minus": 0x2212,
        "lowast": 0x2217,
        "radic": 0x221A,
        "prop": 0x221D,
        "infin": 0x221E,
        "ang": 0x2220,
        "and": 0x2227,
        "or": 0x2228,
        "cap": 0x2229,
        "cup": 0x222A,
        "int": 0x222B,
        "there4": 0x2234,
        "sim": 0x223C,
        "cong": 0x2245,
        "asymp": 0x2248,
        "ne": 0x2260,
        "equiv": 0x2261,
        "le": 0x2264,
        "ge": 0x2265,
        "sub": 0x2282,
        "sup": 0x2283,
        "nsub": 0x2284,
        "sube": 0x2286,
        "supe": 0x2287,
        "oplus": 0x2295,
        "otimes": 0x2297,
        "perp": 0x22A5,
        "sdot": 0x22C5,
        "lceil": 0x2308,
        "rceil": 0x2309,
        "lfloor": 0x230A,
        "rfloor": 0x230B,
        "lang": 0x2329,
        "rang": 0x232A,
        "loz": 0x25CA,
        "spades": 0x2660,
        "clubs": 0x2663,
        "hearts": 0x2665,
        "diams": 0x2666
    });
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
var ts;
(function (ts) {
    function transformES2016(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration;
        return transformSourceFile;
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 32 /* ContainsES2016 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 194 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitBinaryExpression(node) {
            switch (node.operatorToken.kind) {
                case 62 /* AsteriskAsteriskEqualsToken */:
                    return visitExponentiationAssignmentExpression(node);
                case 40 /* AsteriskAsteriskToken */:
                    return visitExponentiationExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitExponentiationAssignmentExpression(node) {
            var target;
            var value;
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            if (ts.isElementAccessExpression(left)) {
                // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                var argumentExpressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createElementAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), ts.setTextRange(ts.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)), left);
                value = ts.setTextRange(ts.createElementAccess(expressionTemp, argumentExpressionTemp), left);
            }
            else if (ts.isPropertyAccessExpression(left)) {
                // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), left.name), left);
                value = ts.setTextRange(ts.createPropertyAccess(expressionTemp, left.name), left);
            }
            else {
                // Transforms `a **= b` into `a = Math.pow(a, b)`
                target = left;
                value = left;
            }
            return ts.setTextRange(ts.createAssignment(target, ts.createMathPow(value, right, /*location*/ node)), node);
        }
        function visitExponentiationExpression(node) {
            // Transforms `a ** b` into `Math.pow(a, b)`
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            return ts.createMathPow(left, right, /*location*/ node);
        }
    }
    ts.transformES2016 = transformES2016;
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/// <reference path="./destructuring.ts" />
/*@internal*/
var ts;
(function (ts) {
    var ES2015SubstitutionFlags;
    (function (ES2015SubstitutionFlags) {
        /** Enables substitutions for captured `this` */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["CapturedThis"] = 1] = "CapturedThis";
        /** Enables substitutions for block-scoped bindings. */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["BlockScopedBindings"] = 2] = "BlockScopedBindings";
    })(ES2015SubstitutionFlags || (ES2015SubstitutionFlags = {}));
    var CopyDirection;
    (function (CopyDirection) {
        CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal";
        CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter";
    })(CopyDirection || (CopyDirection = {}));
    var Jump;
    (function (Jump) {
        Jump[Jump["Break"] = 2] = "Break";
        Jump[Jump["Continue"] = 4] = "Continue";
        Jump[Jump["Return"] = 8] = "Return";
    })(Jump || (Jump = {}));
    var SuperCaptureResult;
    (function (SuperCaptureResult) {
        /**
         * A capture may have been added for calls to 'super', but
         * the caller should emit subsequent statements normally.
         */
        SuperCaptureResult[SuperCaptureResult["NoReplacement"] = 0] = "NoReplacement";
        /**
         * A call to 'super()' got replaced with a capturing statement like:
         *
         *  var _this = _super.call(...) || this;
         *
         * Callers should skip the current statement.
         */
        SuperCaptureResult[SuperCaptureResult["ReplaceSuperCapture"] = 1] = "ReplaceSuperCapture";
        /**
         * A call to 'super()' got replaced with a capturing statement like:
         *
         *  return _super.call(...) || this;
         *
         * Callers should skip the current statement and avoid any returns of '_this'.
         */
        SuperCaptureResult[SuperCaptureResult["ReplaceWithReturn"] = 2] = "ReplaceWithReturn";
    })(SuperCaptureResult || (SuperCaptureResult = {}));
    // Facts we track as we traverse the tree
    var HierarchyFacts;
    (function (HierarchyFacts) {
        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
        //
        // Ancestor facts
        //
        HierarchyFacts[HierarchyFacts["Function"] = 1] = "Function";
        HierarchyFacts[HierarchyFacts["ArrowFunction"] = 2] = "ArrowFunction";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBody"] = 4] = "AsyncFunctionBody";
        HierarchyFacts[HierarchyFacts["NonStaticClassElement"] = 8] = "NonStaticClassElement";
        HierarchyFacts[HierarchyFacts["CapturesThis"] = 16] = "CapturesThis";
        HierarchyFacts[HierarchyFacts["ExportedVariableStatement"] = 32] = "ExportedVariableStatement";
        HierarchyFacts[HierarchyFacts["TopLevel"] = 64] = "TopLevel";
        HierarchyFacts[HierarchyFacts["Block"] = 128] = "Block";
        HierarchyFacts[HierarchyFacts["IterationStatement"] = 256] = "IterationStatement";
        HierarchyFacts[HierarchyFacts["IterationStatementBlock"] = 512] = "IterationStatementBlock";
        HierarchyFacts[HierarchyFacts["ForStatement"] = 1024] = "ForStatement";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatement"] = 2048] = "ForInOrForOfStatement";
        HierarchyFacts[HierarchyFacts["ConstructorWithCapturedSuper"] = 4096] = "ConstructorWithCapturedSuper";
        HierarchyFacts[HierarchyFacts["ComputedPropertyName"] = 8192] = "ComputedPropertyName";
        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
        //
        // Ancestor masks
        //
        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 16383] = "AncestorFactsMask";
        // We are always in *some* kind of block scope, but only specific block-scope containers are
        // top-level or Blocks.
        HierarchyFacts[HierarchyFacts["BlockScopeIncludes"] = 0] = "BlockScopeIncludes";
        HierarchyFacts[HierarchyFacts["BlockScopeExcludes"] = 4032] = "BlockScopeExcludes";
        // A source file is a top-level block scope.
        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 64] = "SourceFileIncludes";
        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 3968] = "SourceFileExcludes";
        // Functions, methods, and accessors are both new lexical scopes and new block scopes.
        HierarchyFacts[HierarchyFacts["FunctionIncludes"] = 65] = "FunctionIncludes";
        HierarchyFacts[HierarchyFacts["FunctionExcludes"] = 16286] = "FunctionExcludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyIncludes"] = 69] = "AsyncFunctionBodyIncludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyExcludes"] = 16278] = "AsyncFunctionBodyExcludes";
        // Arrow functions are lexically scoped to their container, but are new block scopes.
        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 66] = "ArrowFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 16256] = "ArrowFunctionExcludes";
        // Constructors are both new lexical scopes and new block scopes. Constructors are also
        // always considered non-static members of a class.
        HierarchyFacts[HierarchyFacts["ConstructorIncludes"] = 73] = "ConstructorIncludes";
        HierarchyFacts[HierarchyFacts["ConstructorExcludes"] = 16278] = "ConstructorExcludes";
        // 'do' and 'while' statements are not block scopes. We track that the subtree is contained
        // within an IterationStatement to indicate whether the embedded statement is an
        // IterationStatementBlock.
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementIncludes"] = 256] = "DoOrWhileStatementIncludes";
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementExcludes"] = 0] = "DoOrWhileStatementExcludes";
        // 'for' statements are new block scopes and have special handling for 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForStatementIncludes"] = 1280] = "ForStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForStatementExcludes"] = 3008] = "ForStatementExcludes";
        // 'for-in' and 'for-of' statements are new block scopes and have special handling for
        // 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementIncludes"] = 2304] = "ForInOrForOfStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementExcludes"] = 1984] = "ForInOrForOfStatementExcludes";
        // Blocks (other than function bodies) are new block scopes.
        HierarchyFacts[HierarchyFacts["BlockIncludes"] = 128] = "BlockIncludes";
        HierarchyFacts[HierarchyFacts["BlockExcludes"] = 3904] = "BlockExcludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockIncludes"] = 512] = "IterationStatementBlockIncludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockExcludes"] = 4032] = "IterationStatementBlockExcludes";
        // Computed property names track subtree flags differently than their containing members.
        HierarchyFacts[HierarchyFacts["ComputedPropertyNameIncludes"] = 8192] = "ComputedPropertyNameIncludes";
        HierarchyFacts[HierarchyFacts["ComputedPropertyNameExcludes"] = 0] = "ComputedPropertyNameExcludes";
        //
        // Subtree facts
        //
        HierarchyFacts[HierarchyFacts["NewTarget"] = 16384] = "NewTarget";
        HierarchyFacts[HierarchyFacts["NewTargetInComputedPropertyName"] = 32768] = "NewTargetInComputedPropertyName";
        //
        // Subtree masks
        //
        HierarchyFacts[HierarchyFacts["SubtreeFactsMask"] = -16384] = "SubtreeFactsMask";
        HierarchyFacts[HierarchyFacts["PropagateNewTargetMask"] = 49152] = "PropagateNewTargetMask";
    })(HierarchyFacts || (HierarchyFacts = {}));
    function transformES2015(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        var currentSourceFile;
        var currentText;
        var hierarchyFacts;
        var taggedTemplateStringDeclarations;
        function recordTaggedTemplateString(temp) {
            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
        }
        /**
         * Used to track if we are emitting body of the converted loop
         */
        var convertedLoopState;
        /**
         * Keeps track of whether substitutions have been enabled for specific cases.
         * They are persisted between each SourceFile transformation and should not
         * be reset.
         */
        var enabledSubstitutions;
        return transformSourceFile;
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            currentText = node.text;
            var visited = visitSourceFile(node);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            currentText = undefined;
            taggedTemplateStringDeclarations = undefined;
            hierarchyFacts = 0 /* None */;
            return visited;
        }
        /**
         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
         */
        function enterSubtree(excludeFacts, includeFacts) {
            var ancestorFacts = hierarchyFacts;
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 16383 /* AncestorFactsMask */;
            return ancestorFacts;
        }
        /**
         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
         * subtree, propagating specific facts from the subtree.
         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
         * @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated.
         * @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated.
         */
        function exitSubtree(ancestorFacts, excludeFacts, includeFacts) {
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -16384 /* SubtreeFactsMask */ | ancestorFacts;
        }
        function isReturnVoidStatementInConstructorWithCapturedSuper(node) {
            return hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */
                && node.kind === 219 /* ReturnStatement */
                && !node.expression;
        }
        function shouldVisitNode(node) {
            return (node.transformFlags & 128 /* ContainsES2015 */) !== 0
                || convertedLoopState !== undefined
                || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */)))
                || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
        }
        function visitor(node) {
            if (shouldVisitNode(node)) {
                return visitJavaScript(node);
            }
            else {
                return node;
            }
        }
        function functionBodyVisitor(node) {
            if (shouldVisitNode(node)) {
                return visitBlock(node, /*isFunctionBody*/ true);
            }
            return node;
        }
        function callExpressionVisitor(node) {
            if (node.kind === 97 /* SuperKeyword */) {
                return visitSuperKeyword(/*isExpressionOfCall*/ true);
            }
            return visitor(node);
        }
        function visitJavaScript(node) {
            switch (node.kind) {
                case 115 /* StaticKeyword */:
                    return undefined; // elide static keyword
                case 229 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 199 /* ClassExpression */:
                    return visitClassExpression(node);
                case 146 /* Parameter */:
                    return visitParameter(node);
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 187 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 186 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 226 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 71 /* Identifier */:
                    return visitIdentifier(node);
                case 227 /* VariableDeclarationList */:
                    return visitVariableDeclarationList(node);
                case 221 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 235 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 207 /* Block */:
                    return visitBlock(node, /*isFunctionBody*/ false);
                case 218 /* BreakStatement */:
                case 217 /* ContinueStatement */:
                    return visitBreakOrContinueStatement(node);
                case 222 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 212 /* DoStatement */:
                case 213 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, /*outermostLabeledStatement*/ undefined);
                case 214 /* ForStatement */:
                    return visitForStatement(node, /*outermostLabeledStatement*/ undefined);
                case 215 /* ForInStatement */:
                    return visitForInStatement(node, /*outermostLabeledStatement*/ undefined);
                case 216 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 210 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 178 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 260 /* CatchClause */:
                    return visitCatchClause(node);
                case 262 /* ShorthandPropertyAssignment */:
                    return visitShorthandPropertyAssignment(node);
                case 144 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 177 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 181 /* CallExpression */:
                    return visitCallExpression(node);
                case 182 /* NewExpression */:
                    return visitNewExpression(node);
                case 185 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, /*needsDestructuringValue*/ true);
                case 194 /* BinaryExpression */:
                    return visitBinaryExpression(node, /*needsDestructuringValue*/ true);
                case 13 /* NoSubstitutionTemplateLiteral */:
                case 14 /* TemplateHead */:
                case 15 /* TemplateMiddle */:
                case 16 /* TemplateTail */:
                    return visitTemplateLiteral(node);
                case 9 /* StringLiteral */:
                    return visitStringLiteral(node);
                case 8 /* NumericLiteral */:
                    return visitNumericLiteral(node);
                case 183 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 196 /* TemplateExpression */:
                    return visitTemplateExpression(node);
                case 197 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 198 /* SpreadElement */:
                    return visitSpreadElement(node);
                case 97 /* SuperKeyword */:
                    return visitSuperKeyword(/*isExpressionOfCall*/ false);
                case 99 /* ThisKeyword */:
                    return visitThisKeyword(node);
                case 204 /* MetaProperty */:
                    return visitMetaProperty(node);
                case 151 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 208 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 219 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var ancestorFacts = enterSubtree(3968 /* SourceFileExcludes */, 64 /* SourceFileIncludes */);
            var statements = [];
            startLexicalEnvironment();
            var statementOffset = ts.addStandardPrologue(statements, node.statements, /*ensureUseStrict*/ false);
            addCaptureThisForNodeIfNeeded(statements, node);
            statementOffset = ts.addCustomPrologue(statements, node.statements, statementOffset, visitor);
            ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
            if (taggedTemplateStringDeclarations) {
                statements.push(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations)));
            }
            ts.addRange(statements, endLexicalEnvironment());
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
        }
        function visitSwitchStatement(node) {
            if (convertedLoopState !== undefined) {
                var savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                // for switch statement allow only non-labeled break
                convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
                var result = ts.visitEachChild(node, visitor, context);
                convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
                return result;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCaseBlock(node) {
            var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function returnCapturedThis(node) {
            return ts.setOriginalNode(ts.createReturn(ts.createIdentifier("_this")), node);
        }
        function visitReturnStatement(node) {
            if (convertedLoopState) {
                convertedLoopState.nonLocalJumps |= 8 /* Return */;
                if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                    node = returnCapturedThis(node);
                }
                return ts.createReturn(ts.createObjectLiteral([
                    ts.createPropertyAssignment(ts.createIdentifier("value"), node.expression
                        ? ts.visitNode(node.expression, visitor, ts.isExpression)
                        : ts.createVoidZero())
                ]));
            }
            else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                return returnCapturedThis(node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitThisKeyword(node) {
            if (convertedLoopState) {
                if (hierarchyFacts & 2 /* ArrowFunction */) {
                    // if the enclosing function is an ArrowFunction then we use the captured 'this' keyword.
                    convertedLoopState.containsLexicalThis = true;
                    return node;
                }
                return convertedLoopState.thisName || (convertedLoopState.thisName = ts.createUniqueName("this"));
            }
            return node;
        }
        function visitIdentifier(node) {
            if (!convertedLoopState) {
                return node;
            }
            if (ts.isGeneratedIdentifier(node)) {
                return node;
            }
            if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
                return node;
            }
            return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = ts.createUniqueName("arguments"));
        }
        function visitBreakOrContinueStatement(node) {
            if (convertedLoopState) {
                // check if we can emit break/continue as is
                // it is possible if either
                //   - break/continue is labeled and label is located inside the converted loop
                //   - break/continue is non-labeled and located in non-converted loop/switch statement
                var jump = node.kind === 218 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
                var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels.get(ts.idText(node.label))) ||
                    (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
                if (!canUseBreakOrContinue) {
                    var labelMarker = void 0;
                    if (!node.label) {
                        if (node.kind === 218 /* BreakStatement */) {
                            convertedLoopState.nonLocalJumps |= 2 /* Break */;
                            labelMarker = "break";
                        }
                        else {
                            convertedLoopState.nonLocalJumps |= 4 /* Continue */;
                            // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
                            labelMarker = "continue";
                        }
                    }
                    else {
                        if (node.kind === 218 /* BreakStatement */) {
                            labelMarker = "break-" + node.label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ true, ts.idText(node.label), labelMarker);
                        }
                        else {
                            labelMarker = "continue-" + node.label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ false, ts.idText(node.label), labelMarker);
                        }
                    }
                    var returnExpression = ts.createLiteral(labelMarker);
                    if (convertedLoopState.loopOutParameters.length) {
                        var outParams = convertedLoopState.loopOutParameters;
                        var expr = void 0;
                        for (var i = 0; i < outParams.length; i++) {
                            var copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */);
                            if (i === 0) {
                                expr = copyExpr;
                            }
                            else {
                                expr = ts.createBinary(expr, 26 /* CommaToken */, copyExpr);
                            }
                        }
                        returnExpression = ts.createBinary(expr, 26 /* CommaToken */, returnExpression);
                    }
                    return ts.createReturn(returnExpression);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ClassDeclaration and transforms it into a variable statement.
         *
         * @param node A ClassDeclaration node.
         */
        function visitClassDeclaration(node) {
            // [source]
            //      class C { }
            //
            // [output]
            //      var C = (function () {
            //          function C() {
            //          }
            //          return C;
            //      }());
            var variable = ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ true), 
            /*type*/ undefined, transformClassLikeDeclarationToExpression(node));
            ts.setOriginalNode(variable, node);
            var statements = [];
            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([variable]));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, node);
            ts.startOnNewLine(statement);
            statements.push(statement);
            // Add an `export default` statement for default exports (for `--target es5 --module es6`)
            if (ts.hasModifier(node, 1 /* Export */)) {
                var exportStatement = ts.hasModifier(node, 512 /* Default */)
                    ? ts.createExportDefault(ts.getLocalName(node))
                    : ts.createExternalModuleExport(ts.getLocalName(node));
                ts.setOriginalNode(exportStatement, statement);
                statements.push(exportStatement);
            }
            var emitFlags = ts.getEmitFlags(node);
            if ((emitFlags & 4194304 /* HasEndOfDeclarationMarker */) === 0) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(statement, emitFlags | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassExpression and transforms it into an expression.
         *
         * @param node A ClassExpression node.
         */
        function visitClassExpression(node) {
            // [source]
            //      C = class { }
            //
            // [output]
            //      C = (function () {
            //          function class_1() {
            //          }
            //          return class_1;
            //      }())
            return transformClassLikeDeclarationToExpression(node);
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into an expression.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         */
        function transformClassLikeDeclarationToExpression(node) {
            // [source]
            //      class C extends D {
            //          constructor() {}
            //          method() {}
            //          get prop() {}
            //          set prop(v) {}
            //      }
            //
            // [output]
            //      (function (_super) {
            //          __extends(C, _super);
            //          function C() {
            //          }
            //          C.prototype.method = function () {}
            //          Object.defineProperty(C.prototype, "prop", {
            //              get: function() {},
            //              set: function() {},
            //              enumerable: true,
            //              configurable: true
            //          });
            //          return C;
            //      }(D))
            if (node.name) {
                enableSubstitutionsForBlockScopedBindings();
            }
            var extendsClauseElement = ts.getClassExtendsHeritageClauseElement(node);
            var classFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, extendsClauseElement ? [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "_super")] : [], 
            /*type*/ undefined, transformClassBody(node, extendsClauseElement));
            // To preserve the behavior of the old emitter, we explicitly indent
            // the body of the function here if it was requested in an earlier
            // transformation.
            if (ts.getEmitFlags(node) & 65536 /* Indented */) {
                ts.setEmitFlags(classFunction, 65536 /* Indented */);
            }
            // "inner" and "outer" below are added purely to preserve source map locations from
            // the old emitter
            var inner = ts.createPartiallyEmittedExpression(classFunction);
            inner.end = node.end;
            ts.setEmitFlags(inner, 1536 /* NoComments */);
            var outer = ts.createPartiallyEmittedExpression(inner);
            outer.end = ts.skipTrivia(currentText, node.pos);
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var result = ts.createParen(ts.createCall(outer, 
            /*typeArguments*/ undefined, extendsClauseElement
                ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)]
                : []));
            ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class ");
            return result;
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into a function body.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function transformClassBody(node, extendsClauseElement) {
            var statements = [];
            startLexicalEnvironment();
            addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
            addConstructor(statements, node, extendsClauseElement);
            addClassMembers(statements, node);
            // Create a synthetic text range for the return statement.
            var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentText, node.members.end), 18 /* CloseBraceToken */);
            var localName = ts.getInternalName(node);
            // The following partially-emitted expression exists purely to align our sourcemap
            // emit with the original emitter.
            var outer = ts.createPartiallyEmittedExpression(localName);
            outer.end = closingBraceLocation.end;
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var statement = ts.createReturn(outer);
            statement.pos = closingBraceLocation.pos;
            ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
            statements.push(statement);
            ts.addRange(statements, endLexicalEnvironment());
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Adds a call to the `__extends` helper if needed for a class.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) {
            if (extendsClauseElement) {
                statements.push(ts.setTextRange(ts.createStatement(createExtendsHelper(context, ts.getLocalName(node))), 
                /*location*/ extendsClauseElement));
            }
        }
        /**
         * Adds the constructor of the class to a class body function.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addConstructor(statements, node, extendsClauseElement) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16278 /* ConstructorExcludes */, 73 /* ConstructorIncludes */);
            var constructor = ts.getFirstConstructorWithBody(node);
            var hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
            var constructorFunction = ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, ts.getInternalName(node), 
            /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), 
            /*type*/ undefined, transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper));
            ts.setTextRange(constructorFunction, constructor || node);
            if (extendsClauseElement) {
                ts.setEmitFlags(constructorFunction, 8 /* CapturesThis */);
            }
            statements.push(constructorFunction);
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
        }
        /**
         * Transforms the parameters of the constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorParameters(constructor, hasSynthesizedSuper) {
            // If the TypeScript transformer needed to synthesize a constructor for property
            // initializers, it would have also added a synthetic `...args` parameter and
            // `super` call.
            // If this is the case, we do not include the synthetic `...args` parameter and
            // will instead use the `arguments` object in ES5/3.
            return ts.visitParameterList(constructor && !hasSynthesizedSuper && constructor.parameters, visitor, context)
                || [];
        }
        /**
         * Transforms the body of a constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param node The node which contains the constructor.
         * @param extendsClauseElement The expression for the class `extends` clause.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) {
            var statements = [];
            resumeLexicalEnvironment();
            var statementOffset = -1;
            if (hasSynthesizedSuper) {
                // If a super call has already been synthesized,
                // we're going to assume that we should just transform everything after that.
                // The assumption is that no prior step in the pipeline has added any prologue directives.
                statementOffset = 0;
            }
            else if (constructor) {
                statementOffset = ts.addStandardPrologue(statements, constructor.body.statements, /*ensureUseStrict*/ false);
            }
            if (constructor) {
                addDefaultValueAssignmentsIfNeeded(statements, constructor);
                addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
                if (!hasSynthesizedSuper) {
                    // If no super call has been synthesized, emit custom prologue directives.
                    statementOffset = ts.addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
                }
                ts.Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
            }
            // determine whether the class is known syntactically to be a derived class (e.g. a
            // class that extends a value that is not syntactically known to be `null`).
            var isDerivedClass = extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 95 /* NullKeyword */;
            var superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, constructor, isDerivedClass, hasSynthesizedSuper, statementOffset);
            // The last statement expression was replaced. Skip it.
            if (superCaptureStatus === 1 /* ReplaceSuperCapture */ || superCaptureStatus === 2 /* ReplaceWithReturn */) {
                statementOffset++;
            }
            if (constructor) {
                if (superCaptureStatus === 1 /* ReplaceSuperCapture */) {
                    hierarchyFacts |= 4096 /* ConstructorWithCapturedSuper */;
                }
                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, /*start*/ statementOffset));
            }
            // Return `_this` unless we're sure enough that it would be pointless to add a return statement.
            // If there's a constructor that we can tell returns in enough places, then we *do not* want to add a return.
            if (isDerivedClass
                && superCaptureStatus !== 2 /* ReplaceWithReturn */
                && !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body))) {
                statements.push(ts.createReturn(ts.createIdentifier("_this")));
            }
            ts.addRange(statements, endLexicalEnvironment());
            if (constructor) {
                prependCaptureNewTargetIfNeeded(statements, constructor, /*copyOnWrite*/ false);
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ constructor ? constructor.body.statements : node.members), 
            /*multiLine*/ true);
            ts.setTextRange(block, constructor ? constructor.body : node);
            if (!constructor) {
                ts.setEmitFlags(block, 1536 /* NoComments */);
            }
            return block;
        }
        /**
         * We want to try to avoid emitting a return statement in certain cases if a user already returned something.
         * It would generate obviously dead code, so we'll try to make things a little bit prettier
         * by doing a minimal check on whether some common patterns always explicitly return.
         */
        function isSufficientlyCoveredByReturnStatements(statement) {
            // A return statement is considered covered.
            if (statement.kind === 219 /* ReturnStatement */) {
                return true;
            }
            else if (statement.kind === 211 /* IfStatement */) {
                var ifStatement = statement;
                if (ifStatement.elseStatement) {
                    return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) &&
                        isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement);
                }
            }
            else if (statement.kind === 207 /* Block */) {
                var lastStatement = ts.lastOrUndefined(statement.statements);
                if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Declares a `_this` variable for derived classes and for when arrow functions capture `this`.
         *
         * @returns The new statement offset into the `statements` array.
         */
        function declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, ctor, isDerivedClass, hasSynthesizedSuper, statementOffset) {
            // If this isn't a derived class, just capture 'this' for arrow functions if necessary.
            if (!isDerivedClass) {
                if (ctor) {
                    addCaptureThisForNodeIfNeeded(statements, ctor);
                }
                return 0 /* NoReplacement */;
            }
            // We must be here because the user didn't write a constructor
            // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec.
            // If that's the case we can just immediately return the result of a 'super()' call.
            if (!ctor) {
                statements.push(ts.createReturn(createDefaultSuperCallOrThis()));
                return 2 /* ReplaceWithReturn */;
            }
            // The constructor exists, but it and the 'super()' call it contains were generated
            // for something like property initializers.
            // Create a captured '_this' variable and assume it will subsequently be used.
            if (hasSynthesizedSuper) {
                captureThisForNode(statements, ctor, createDefaultSuperCallOrThis());
                enableSubstitutionsForCapturedThis();
                return 1 /* ReplaceSuperCapture */;
            }
            // Most of the time, a 'super' call will be the first real statement in a constructor body.
            // In these cases, we'd like to transform these into a *single* statement instead of a declaration
            // followed by an assignment statement for '_this'. For instance, if we emitted without an initializer,
            // we'd get:
            //
            //      var _this;
            //      _this = _super.call(...) || this;
            //
            // instead of
            //
            //      var _this = _super.call(...) || this;
            //
            // Additionally, if the 'super()' call is the last statement, we should just avoid capturing
            // entirely and immediately return the result like so:
            //
            //      return _super.call(...) || this;
            //
            var firstStatement;
            var superCallExpression;
            var ctorStatements = ctor.body.statements;
            if (statementOffset < ctorStatements.length) {
                firstStatement = ctorStatements[statementOffset];
                if (firstStatement.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(firstStatement.expression)) {
                    superCallExpression = visitImmediateSuperCallInBody(firstStatement.expression);
                }
            }
            // Return the result if we have an immediate super() call on the last statement,
            // but only if the constructor itself doesn't use 'this' elsewhere.
            if (superCallExpression
                && statementOffset === ctorStatements.length - 1
                && !(ctor.transformFlags & (16384 /* ContainsLexicalThis */ | 32768 /* ContainsCapturedLexicalThis */))) {
                var returnStatement = ts.createReturn(superCallExpression);
                if (superCallExpression.kind !== 194 /* BinaryExpression */
                    || superCallExpression.left.kind !== 181 /* CallExpression */) {
                    ts.Debug.fail("Assumed generated super call would have form 'super.call(...) || this'.");
                }
                // Shift comments from the original super call to the return statement.
                ts.setCommentRange(returnStatement, ts.getCommentRange(ts.setEmitFlags(superCallExpression.left, 1536 /* NoComments */)));
                statements.push(returnStatement);
                return 2 /* ReplaceWithReturn */;
            }
            // Perform the capture.
            captureThisForNode(statements, ctor, superCallExpression || createActualThis(), firstStatement);
            // If we're actually replacing the original statement, we need to signal this to the caller.
            if (superCallExpression) {
                return 1 /* ReplaceSuperCapture */;
            }
            return 0 /* NoReplacement */;
        }
        function createActualThis() {
            return ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */);
        }
        function createDefaultSuperCallOrThis() {
            return ts.createLogicalOr(ts.createLogicalAnd(ts.createStrictInequality(ts.createIdentifier("_super"), ts.createNull()), ts.createFunctionApply(ts.createIdentifier("_super"), createActualThis(), ts.createIdentifier("arguments"))), createActualThis());
        }
        /**
         * Visits a parameter declaration.
         *
         * @param node A ParameterDeclaration node.
         */
        function visitParameter(node) {
            if (node.dotDotDotToken) {
                // rest parameters are elided
                return undefined;
            }
            else if (ts.isBindingPattern(node.name)) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else if (node.initializer) {
                // Initializers are elided
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, node.name, 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else {
                return node;
            }
        }
        /**
         * Gets a value indicating whether we need to add default value assignments for a
         * function-like node.
         *
         * @param node A function-like node.
         */
        function shouldAddDefaultValueAssignments(node) {
            return (node.transformFlags & 131072 /* ContainsDefaultValueAssignments */) !== 0;
        }
        /**
         * Adds statements to the body of a function-like node if it contains parameters with
         * binding patterns or initializers.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         */
        function addDefaultValueAssignmentsIfNeeded(statements, node) {
            if (!shouldAddDefaultValueAssignments(node)) {
                return;
            }
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                var name = parameter.name, initializer = parameter.initializer, dotDotDotToken = parameter.dotDotDotToken;
                // A rest parameter cannot have a binding pattern or an initializer,
                // so let's just ignore it.
                if (dotDotDotToken) {
                    continue;
                }
                if (ts.isBindingPattern(name)) {
                    addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer);
                }
                else if (initializer) {
                    addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
                }
            }
        }
        /**
         * Adds statements to the body of a function-like node for parameters with binding patterns
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) {
            var temp = ts.getGeneratedNameForNode(parameter);
            // In cases where a binding pattern is simply '[]' or '{}',
            // we usually don't want to emit a var declaration; however, in the presence
            // of an initializer, we must emit that expression to preserve side effects.
            if (name.elements.length > 0) {
                statements.push(ts.setEmitFlags(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, temp))), 1048576 /* CustomPrologue */));
            }
            else if (initializer) {
                statements.push(ts.setEmitFlags(ts.createStatement(ts.createAssignment(temp, ts.visitNode(initializer, visitor, ts.isExpression))), 1048576 /* CustomPrologue */));
            }
        }
        /**
         * Adds statements to the body of a function-like node for parameters with initializers.
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) {
            initializer = ts.visitNode(initializer, visitor, ts.isExpression);
            var statement = ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
                ts.createStatement(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer))), parameter))
            ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */));
            statement.startsOnNewLine = true;
            ts.setTextRange(statement, parameter);
            ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1048576 /* CustomPrologue */);
            statements.push(statement);
        }
        /**
         * Gets a value indicating whether we need to add statements to handle a rest parameter.
         *
         * @param node A ParameterDeclaration node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) {
            return node && node.dotDotDotToken && node.name.kind === 71 /* Identifier */ && !inConstructorWithSynthesizedSuper;
        }
        /**
         * Adds statements to the body of a function-like node if it contains a rest parameter.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) {
            var parameter = ts.lastOrUndefined(node.parameters);
            if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
                return;
            }
            // `declarationName` is the name of the local declaration for the parameter.
            var declarationName = ts.getMutableClone(parameter.name);
            ts.setEmitFlags(declarationName, 48 /* NoSourceMap */);
            // `expressionName` is the name of the parameter used in expressions.
            var expressionName = ts.getSynthesizedClone(parameter.name);
            var restIndex = node.parameters.length - 1;
            var temp = ts.createLoopVariable();
            // var param = [];
            statements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declarationName, 
                /*type*/ undefined, ts.createArrayLiteral([]))
            ])), 
            /*location*/ parameter), 1048576 /* CustomPrologue */));
            // for (var _i = restIndex; _i < arguments.length; _i++) {
            //   param[_i - restIndex] = arguments[_i];
            // }
            var forStatement = ts.createFor(ts.setTextRange(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(temp, /*type*/ undefined, ts.createLiteral(restIndex))
            ]), parameter), ts.setTextRange(ts.createLessThan(temp, ts.createPropertyAccess(ts.createIdentifier("arguments"), "length")), parameter), ts.setTextRange(ts.createPostfixIncrement(temp), parameter), ts.createBlock([
                ts.startOnNewLine(ts.setTextRange(ts.createStatement(ts.createAssignment(ts.createElementAccess(expressionName, restIndex === 0
                    ? temp
                    : ts.createSubtract(temp, ts.createLiteral(restIndex))), ts.createElementAccess(ts.createIdentifier("arguments"), temp))), 
                /*location*/ parameter))
            ]));
            ts.setEmitFlags(forStatement, 1048576 /* CustomPrologue */);
            ts.startOnNewLine(forStatement);
            statements.push(forStatement);
        }
        /**
         * Adds a statement to capture the `this` of a function declaration if it is needed.
         *
         * @param statements The statements for the new function body.
         * @param node A node.
         */
        function addCaptureThisForNodeIfNeeded(statements, node) {
            if (node.transformFlags & 32768 /* ContainsCapturedLexicalThis */ && node.kind !== 187 /* ArrowFunction */) {
                captureThisForNode(statements, node, ts.createThis());
            }
        }
        function captureThisForNode(statements, node, initializer, originalStatement) {
            enableSubstitutionsForCapturedThis();
            var captureThisStatement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration("_this", 
                /*type*/ undefined, initializer)
            ]));
            ts.setEmitFlags(captureThisStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
            ts.setTextRange(captureThisStatement, originalStatement);
            ts.setSourceMapRange(captureThisStatement, node);
            statements.push(captureThisStatement);
        }
        function prependCaptureNewTargetIfNeeded(statements, node, copyOnWrite) {
            if (hierarchyFacts & 16384 /* NewTarget */) {
                var newTarget = void 0;
                switch (node.kind) {
                    case 187 /* ArrowFunction */:
                        return statements;
                    case 151 /* MethodDeclaration */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        // Methods and accessors cannot be constructors, so 'new.target' will
                        // always return 'undefined'.
                        newTarget = ts.createVoidZero();
                        break;
                    case 152 /* Constructor */:
                        // Class constructors can only be called with `new`, so `this.constructor`
                        // should be relatively safe to use.
                        newTarget = ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor");
                        break;
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                        // Functions can be called or constructed, and may have a `this` due to
                        // being a member or when calling an imported function via `other_1.f()`.
                        newTarget = ts.createConditional(ts.createLogicalAnd(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), ts.createBinary(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), 93 /* InstanceOfKeyword */, ts.getLocalName(node))), ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"), ts.createVoidZero());
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
                var captureNewTargetStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration("_newTarget", 
                    /*type*/ undefined, newTarget)
                ]));
                if (copyOnWrite) {
                    return [captureNewTargetStatement].concat(statements);
                }
                statements.unshift(captureNewTargetStatement);
            }
            return statements;
        }
        /**
         * Adds statements to the class body function for a class to define the members of the
         * class.
         *
         * @param statements The statements for the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         */
        function addClassMembers(statements, node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 206 /* SemicolonClassElement */:
                        statements.push(transformSemicolonClassElementToStatement(member));
                        break;
                    case 151 /* MethodDeclaration */:
                        statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node));
                        break;
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
                        if (member === accessors.firstAccessor) {
                            statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node));
                        }
                        break;
                    case 152 /* Constructor */:
                        // Constructors are handled in visitClassExpression/visitClassDeclaration
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
            }
        }
        /**
         * Transforms a SemicolonClassElement into a statement for a class body function.
         *
         * @param member The SemicolonClassElement node.
         */
        function transformSemicolonClassElementToStatement(member) {
            return ts.setTextRange(ts.createEmptyStatement(), member);
        }
        /**
         * Transforms a MethodDeclaration into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param member The MethodDeclaration node.
         */
        function transformClassMethodDeclarationToStatement(receiver, member, container) {
            var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */);
            var commentRange = ts.getCommentRange(member);
            var sourceMapRange = ts.getSourceMapRange(member);
            var memberName = ts.createMemberAccessForPropertyName(receiver, ts.visitNode(member.name, visitor, ts.isPropertyName), /*location*/ member.name);
            var memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container);
            ts.setEmitFlags(memberFunction, 1536 /* NoComments */);
            ts.setSourceMapRange(memberFunction, sourceMapRange);
            var statement = ts.setTextRange(ts.createStatement(ts.createAssignment(memberName, memberFunction)), 
            /*location*/ member);
            ts.setOriginalNode(statement, member);
            ts.setCommentRange(statement, commentRange);
            // The location for the statement is used to emit comments only.
            // No source map should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 48 /* NoSourceMap */);
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */);
            return statement;
        }
        /**
         * Transforms a set of related of get/set accessors into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param accessors The set of related get/set accessors.
         */
        function transformAccessorsToStatement(receiver, accessors, container) {
            var statement = ts.createStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
            // The location for the statement is used to emit source maps only.
            // No comments should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 1536 /* NoComments */);
            ts.setSourceMapRange(statement, ts.getSourceMapRange(accessors.firstAccessor));
            return statement;
        }
        /**
         * Transforms a set of related get/set accessors into an expression for either a class
         * body function or an ObjectLiteralExpression with computed properties.
         *
         * @param receiver The receiver for the member.
         */
        function transformAccessorsToExpression(receiver, _a, container, startsOnNewLine) {
            var firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
            var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */);
            // To align with source maps in the old emitter, the receiver and property name
            // arguments are both mapped contiguously to the accessor name.
            var target = ts.getMutableClone(receiver);
            ts.setEmitFlags(target, 1536 /* NoComments */ | 32 /* NoTrailingSourceMap */);
            ts.setSourceMapRange(target, firstAccessor.name);
            var propertyName = ts.createExpressionForPropertyName(ts.visitNode(firstAccessor.name, visitor, ts.isPropertyName));
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 16 /* NoLeadingSourceMap */);
            ts.setSourceMapRange(propertyName, firstAccessor.name);
            var properties = [];
            if (getAccessor) {
                var getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(getterFunction, ts.getSourceMapRange(getAccessor));
                ts.setEmitFlags(getterFunction, 512 /* NoLeadingComments */);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                ts.setCommentRange(getter, ts.getCommentRange(getAccessor));
                properties.push(getter);
            }
            if (setAccessor) {
                var setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(setterFunction, ts.getSourceMapRange(setAccessor));
                ts.setEmitFlags(setterFunction, 512 /* NoLeadingComments */);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                ts.setCommentRange(setter, ts.getCommentRange(setAccessor));
                properties.push(setter);
            }
            properties.push(ts.createPropertyAssignment("enumerable", ts.createTrue()), ts.createPropertyAssignment("configurable", ts.createTrue()));
            var call = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                target,
                propertyName,
                ts.createObjectLiteral(properties, /*multiLine*/ true)
            ]);
            if (startsOnNewLine) {
                call.startsOnNewLine = true;
            }
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */);
            return call;
        }
        /**
         * Visits an ArrowFunction and transforms it into a FunctionExpression.
         *
         * @param node An ArrowFunction node.
         */
        function visitArrowFunction(node) {
            if (node.transformFlags & 16384 /* ContainsLexicalThis */) {
                enableSubstitutionsForCapturedThis();
            }
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16256 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */);
            var func = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            ts.setTextRange(func, node);
            ts.setOriginalNode(func, node);
            ts.setEmitFlags(func, 8 /* CapturesThis */);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return func;
        }
        /**
         * Visits a FunctionExpression node.
         *
         * @param node a FunctionExpression node.
         */
        function visitFunctionExpression(node) {
            var ancestorFacts = ts.getEmitFlags(node) & 262144 /* AsyncFunctionBody */
                ? enterSubtree(16278 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = node.transformFlags & 64 /* ES2015 */
                ? transformFunctionBody(node)
                : visitFunctionBodyDownLevel(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionExpression(node, 
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node a FunctionDeclaration node.
         */
        function visitFunctionDeclaration(node) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = node.transformFlags & 64 /* ES2015 */
                ? transformFunctionBody(node)
                : visitFunctionBodyDownLevel(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Transforms a function-like node into a FunctionExpression.
         *
         * @param node The function-like node to transform.
         * @param location The source-map location for the new FunctionExpression.
         * @param name The name of the new FunctionExpression.
         */
        function transformFunctionLikeToExpression(node, location, name, container) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = container && ts.isClassLike(container) && !ts.hasModifier(node, 32 /* Static */)
                ? enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (hierarchyFacts & 16384 /* NewTarget */ && !name && (node.kind === 228 /* FunctionDeclaration */ || node.kind === 186 /* FunctionExpression */)) {
                name = ts.getGeneratedNameForNode(node);
            }
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body), location), 
            /*original*/ node);
        }
        /**
         * Transforms the body of a function-like node.
         *
         * @param node A function-like node.
         */
        function transformFunctionBody(node) {
            var multiLine = false; // indicates whether the block *must* be emitted as multiple lines
            var singleLine = false; // indicates whether the block *may* be emitted as a single line
            var statementsLocation;
            var closeBraceLocation;
            var statements = [];
            var body = node.body;
            var statementOffset;
            resumeLexicalEnvironment();
            if (ts.isBlock(body)) {
                // ensureUseStrict is false because no new prologue-directive should be added.
                // addStandardPrologue will put already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addStandardPrologue(statements, body.statements, /*ensureUseStrict*/ false);
            }
            addCaptureThisForNodeIfNeeded(statements, node);
            addDefaultValueAssignmentsIfNeeded(statements, node);
            addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
            // If we added any generated statements, this must be a multi-line block.
            if (!multiLine && statements.length > 0) {
                multiLine = true;
            }
            if (ts.isBlock(body)) {
                // addCustomPrologue puts already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor);
                statementsLocation = body.statements;
                ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, statementOffset));
                // If the original body was a multi-line block, this must be a multi-line block.
                if (!multiLine && body.multiLine) {
                    multiLine = true;
                }
            }
            else {
                ts.Debug.assert(node.kind === 187 /* ArrowFunction */);
                // To align with the old emitter, we use a synthetic end position on the location
                // for the statement list we synthesize when we down-level an arrow function with
                // an expression function body. This prevents both comments and source maps from
                // being emitted for the end position only.
                statementsLocation = ts.moveRangeEnd(body, -1);
                var equalsGreaterThanToken = node.equalsGreaterThanToken;
                if (!ts.nodeIsSynthesized(equalsGreaterThanToken) && !ts.nodeIsSynthesized(body)) {
                    if (ts.rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
                        singleLine = true;
                    }
                    else {
                        multiLine = true;
                    }
                }
                var expression = ts.visitNode(body, visitor, ts.isExpression);
                var returnStatement = ts.createReturn(expression);
                ts.setTextRange(returnStatement, body);
                ts.setEmitFlags(returnStatement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1024 /* NoTrailingComments */);
                statements.push(returnStatement);
                // To align with the source map emit for the old emitter, we set a custom
                // source map location for the close brace.
                closeBraceLocation = body;
            }
            var lexicalEnvironment = context.endLexicalEnvironment();
            ts.addRange(statements, lexicalEnvironment);
            prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false);
            // If we added any final generated statements, this must be a multi-line block
            if (!multiLine && lexicalEnvironment && lexicalEnvironment.length) {
                multiLine = true;
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), multiLine);
            ts.setTextRange(block, node.body);
            if (!multiLine && singleLine) {
                ts.setEmitFlags(block, 1 /* SingleLine */);
            }
            if (closeBraceLocation) {
                ts.setTokenSourceMapRange(block, 18 /* CloseBraceToken */, closeBraceLocation);
            }
            ts.setOriginalNode(block, node.body);
            return block;
        }
        function visitFunctionBodyDownLevel(node) {
            var updated = ts.visitFunctionBody(node.body, functionBodyVisitor, context);
            return ts.updateBlock(updated, ts.setTextRange(ts.createNodeArray(prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)), 
            /*location*/ updated.statements));
        }
        function visitBlock(node, isFunctionBody) {
            if (isFunctionBody) {
                // A function body is not a block scope.
                return ts.visitEachChild(node, visitor, context);
            }
            var ancestorFacts = hierarchyFacts & 256 /* IterationStatement */
                ? enterSubtree(4032 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */)
                : enterSubtree(3904 /* BlockExcludes */, 128 /* BlockIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits an ExpressionStatement that contains a destructuring assignment.
         *
         * @param node An ExpressionStatement node.
         */
        function visitExpressionStatement(node) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            switch (node.expression.kind) {
                case 185 /* ParenthesizedExpression */:
                    return ts.updateStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                case 194 /* BinaryExpression */:
                    return ts.updateStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ParenthesizedExpression that may contain a destructuring assignment.
         *
         * @param node A ParenthesizedExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitParenthesizedExpression(node, needsDestructuringValue) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            if (!needsDestructuringValue) {
                // By default we always emit the RHS at the end of a flattened destructuring
                // expression. If we are in a state where we do not need the destructuring value,
                // we pass that information along to the children that care about it.
                switch (node.expression.kind) {
                    case 185 /* ParenthesizedExpression */:
                        return ts.updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                    case 194 /* BinaryExpression */:
                        return ts.updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitBinaryExpression(node, needsDestructuringValue) {
            // If we are here it is because this is a destructuring assignment.
            if (ts.isDestructuringAssignment(node)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, needsDestructuringValue);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitVariableStatement(node) {
            var ancestorFacts = enterSubtree(0 /* None */, ts.hasModifier(node, 1 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */);
            var updated;
            if (convertedLoopState && (node.declarationList.flags & 3 /* BlockScoped */) === 0) {
                // we are inside a converted loop - hoist variable declarations
                var assignments = void 0;
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
                    if (decl.initializer) {
                        var assignment = void 0;
                        if (ts.isBindingPattern(decl.name)) {
                            assignment = ts.flattenDestructuringAssignment(decl, visitor, context, 0 /* All */);
                        }
                        else {
                            assignment = ts.createBinary(decl.name, 58 /* EqualsToken */, ts.visitNode(decl.initializer, visitor, ts.isExpression));
                            ts.setTextRange(assignment, decl);
                        }
                        assignments = ts.append(assignments, assignment);
                    }
                }
                if (assignments) {
                    updated = ts.setTextRange(ts.createStatement(ts.inlineExpressions(assignments)), node);
                }
                else {
                    // none of declarations has initializer - the entire variable statement can be deleted
                    updated = undefined;
                }
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`).
         *
         * @param node A VariableDeclarationList node.
         */
        function visitVariableDeclarationList(node) {
            if (node.transformFlags & 64 /* ES2015 */) {
                if (node.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var declarations = ts.flatMap(node.declarations, node.flags & 1 /* Let */
                    ? visitVariableDeclarationInLetDeclarationList
                    : visitVariableDeclaration);
                var declarationList = ts.createVariableDeclarationList(declarations);
                ts.setOriginalNode(declarationList, node);
                ts.setTextRange(declarationList, node);
                ts.setCommentRange(declarationList, node);
                if (node.transformFlags & 8388608 /* ContainsBindingPattern */
                    && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) {
                    // If the first or last declaration is a binding pattern, we need to modify
                    // the source map range for the declaration list.
                    var firstDeclaration = ts.firstOrUndefined(declarations);
                    if (firstDeclaration) {
                        var lastDeclaration = ts.lastOrUndefined(declarations);
                        ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end));
                    }
                }
                return declarationList;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Gets a value indicating whether we should emit an explicit initializer for a variable
         * declaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function shouldEmitExplicitInitializerForLetDeclaration(node) {
            // Nested let bindings might need to be initialized explicitly to preserve
            // ES6 semantic:
            //
            //  { let x = 1; }
            //  { let x; } // x here should be undefined. not 1
            //
            // Top level bindings never collide with anything and thus don't require
            // explicit initialization. As for nested let bindings there are two cases:
            //
            // - Nested let bindings that were not renamed definitely should be
            //   initialized explicitly:
            //
            //    { let x = 1; }
            //    { let x; if (some-condition) { x = 1}; if (x) { /*1*/ } }
            //
            //   Without explicit initialization code in /*1*/ can be executed even if
            //   some-condition is evaluated to false.
            //
            // - Renaming introduces fresh name that should not collide with any
            //   existing names, however renamed bindings sometimes also should be
            //   explicitly initialized. One particular case: non-captured binding
            //   declared inside loop body (but not in loop initializer):
            //
            //    let x;
            //    for (;;) {
            //        let x;
            //    }
            //
            //   In downlevel codegen inner 'x' will be renamed so it won't collide
            //   with outer 'x' however it will should be reset on every iteration as
            //   if it was declared anew.
            //
            //   * Why non-captured binding?
            //     - Because if loop contains block scoped binding captured in some
            //       function then loop body will be rewritten to have a fresh scope
            //       on every iteration so everything will just work.
            //
            //   * Why loop initializer is excluded?
            //     - Since we've introduced a fresh name it already will be undefined.
            var flags = resolver.getNodeCheckFlags(node);
            var isCapturedInFunction = flags & 131072 /* CapturedBlockScopedBinding */;
            var isDeclaredInLoop = flags & 262144 /* BlockScopedBindingInLoop */;
            var emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0
                || (isCapturedInFunction
                    && isDeclaredInLoop
                    && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0);
            var emitExplicitInitializer = !emittedAsTopLevel
                && (hierarchyFacts & 2048 /* ForInOrForOfStatement */) === 0
                && (!resolver.isDeclarationWithCollidingName(node)
                    || (isDeclaredInLoop
                        && !isCapturedInFunction
                        && (hierarchyFacts & (1024 /* ForStatement */ | 2048 /* ForInOrForOfStatement */)) === 0));
            return emitExplicitInitializer;
        }
        /**
         * Visits a VariableDeclaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclarationInLetDeclarationList(node) {
            // For binding pattern names that lack initializers there is no point to emit
            // explicit initializer since downlevel codegen for destructuring will fail
            // in the absence of initializer so all binding elements will say uninitialized
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return visitVariableDeclaration(node);
            }
            if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
                var clone_2 = ts.getMutableClone(node);
                clone_2.initializer = ts.createVoidZero();
                return clone_2;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            var ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */);
            var updated;
            if (ts.isBindingPattern(node.name)) {
                updated = ts.flattenDestructuringBinding(node, visitor, context, 0 /* All */, 
                /*value*/ undefined, (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0);
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function recordLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), true);
        }
        function resetLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), false);
        }
        function visitLabeledStatement(node) {
            if (convertedLoopState && !convertedLoopState.labels) {
                convertedLoopState.labels = ts.createMap();
            }
            var statement = ts.unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
            return ts.isIterationStatement(statement, /*lookInLabeledStatements*/ false)
                ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
                : ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement), node, convertedLoopState && resetLabel);
        }
        function visitIterationStatement(node, outermostLabeledStatement) {
            switch (node.kind) {
                case 212 /* DoStatement */:
                case 213 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, outermostLabeledStatement);
                case 214 /* ForStatement */:
                    return visitForStatement(node, outermostLabeledStatement);
                case 215 /* ForInStatement */:
                    return visitForInStatement(node, outermostLabeledStatement);
                case 216 /* ForOfStatement */:
                    return visitForOfStatement(node, outermostLabeledStatement);
            }
        }
        function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) {
            var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
            var updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function visitDoOrWhileStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(0 /* DoOrWhileStatementExcludes */, 256 /* DoOrWhileStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForStatementExcludes */, 1280 /* ForStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForInStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(1984 /* ForInOrForOfStatementExcludes */, 2304 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForOfStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(1984 /* ForInOrForOfStatementExcludes */, 2304 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement, compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
        }
        function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) {
            var statements = [];
            if (ts.isVariableDeclarationList(node.initializer)) {
                if (node.initializer.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var firstOriginalDeclaration = ts.firstOrUndefined(node.initializer.declarations);
                if (firstOriginalDeclaration && ts.isBindingPattern(firstOriginalDeclaration.name)) {
                    // This works whether the declaration is a var, let, or const.
                    // It will use rhsIterationValue _a[_i] as the initializer.
                    var declarations = ts.flattenDestructuringBinding(firstOriginalDeclaration, visitor, context, 0 /* All */, boundValue);
                    var declarationList = ts.setTextRange(ts.createVariableDeclarationList(declarations), node.initializer);
                    ts.setOriginalNode(declarationList, node.initializer);
                    // Adjust the source map range for the first declaration to align with the old
                    // emitter.
                    var firstDeclaration = declarations[0];
                    var lastDeclaration = ts.lastOrUndefined(declarations);
                    ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end));
                    statements.push(ts.createVariableStatement(
                    /*modifiers*/ undefined, declarationList));
                }
                else {
                    // The following call does not include the initializer, so we have
                    // to emit it separately.
                    statements.push(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(firstOriginalDeclaration ? firstOriginalDeclaration.name : ts.createTempVariable(/*recordTempVariable*/ undefined), 
                        /*type*/ undefined, boundValue)
                    ]), ts.moveRangePos(node.initializer, -1)), node.initializer)), ts.moveRangeEnd(node.initializer, -1)));
                }
            }
            else {
                // Initializer is an expression. Emit the expression in the body, so that it's
                // evaluated on every iteration.
                var assignment = ts.createAssignment(node.initializer, boundValue);
                if (ts.isDestructuringAssignment(assignment)) {
                    ts.aggregateTransformFlags(assignment);
                    statements.push(ts.createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
                }
                else {
                    assignment.end = node.initializer.end;
                    statements.push(ts.setTextRange(ts.createStatement(ts.visitNode(assignment, visitor, ts.isExpression)), ts.moveRangeEnd(node.initializer, -1)));
                }
            }
            var bodyLocation;
            var statementsLocation;
            if (convertedLoopBodyStatements) {
                ts.addRange(statements, convertedLoopBodyStatements);
            }
            else {
                var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
                if (ts.isBlock(statement)) {
                    ts.addRange(statements, statement.statements);
                    bodyLocation = statement;
                    statementsLocation = statement.statements;
                }
                else {
                    statements.push(statement);
                }
            }
            // The old emitter does not emit source maps for the block.
            // We add the location to preserve comments.
            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) {
            // The following ES6 code:
            //
            //    for (let v of expr) { }
            //
            // should be emitted as
            //
            //    for (var _i = 0, _a = expr; _i < _a.length; _i++) {
            //        var 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 expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            // 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 counter = ts.createLoopVariable();
            var rhsReference = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            // The old emitter does not emit source maps for the expression
            ts.setEmitFlags(expression, 48 /* NoSourceMap */ | ts.getEmitFlags(expression));
            var forStatement = ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(counter, /*type*/ undefined, ts.createLiteral(0)), ts.moveRangePos(node.expression, -1)),
                ts.setTextRange(ts.createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.setTextRange(ts.createLessThan(counter, ts.createPropertyAccess(rhsReference, "length")), node.expression), 
            /*incrementor*/ ts.setTextRange(ts.createPostfixIncrement(counter), node.expression), 
            /*statement*/ convertForOfStatementHead(node, ts.createElementAccess(rhsReference, counter), convertedLoopBodyStatements)), 
            /*location*/ node);
            // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
            ts.setEmitFlags(forStatement, 256 /* NoTokenTrailingSourceMaps */);
            ts.setTextRange(forStatement, node);
            return ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
        }
        function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var values = ts.createValuesHelper(context, expression, node.expression);
            var next = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
                ts.createVariableDeclaration(result, /*type*/ undefined, next)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createLogicalNot(ts.createPropertyAccess(result, "done")), 
            /*incrementor*/ ts.createAssignment(result, next), 
            /*statement*/ convertForOfStatementHead(node, ts.createPropertyAccess(result, "value"), convertedLoopBodyStatements)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(ts.createPropertyAccess(result, "done"))), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createStatement(ts.createFunctionCall(returnMethod, iterator, []))), 1 /* SingleLine */),
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        /**
         * Visits an ObjectLiteralExpression with computed propety names.
         *
         * @param node An ObjectLiteralExpression node.
         */
        function visitObjectLiteralExpression(node) {
            // We are here because a ComputedPropertyName was used somewhere in the expression.
            var properties = node.properties;
            var numProperties = properties.length;
            // Find the first computed property.
            // Everything until that point can be emitted as part of the initial object literal.
            var numInitialProperties = numProperties;
            var numInitialPropertiesWithoutYield = numProperties;
            for (var i = 0; i < numProperties; i++) {
                var property = properties[i];
                if ((property.transformFlags & 16777216 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */)
                    && i < numInitialPropertiesWithoutYield) {
                    numInitialPropertiesWithoutYield = i;
                }
                if (property.name.kind === 144 /* ComputedPropertyName */) {
                    numInitialProperties = i;
                    break;
                }
            }
            if (numInitialProperties !== numProperties) {
                if (numInitialPropertiesWithoutYield < numInitialProperties) {
                    numInitialProperties = numInitialPropertiesWithoutYield;
                }
                // 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 temp = ts.createTempVariable(hoistVariableDeclaration);
                // Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
                var expressions = [];
                var assignment = ts.createAssignment(temp, ts.setEmitFlags(ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine), 65536 /* Indented */));
                if (node.multiLine) {
                    assignment.startsOnNewLine = true;
                }
                expressions.push(assignment);
                addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
                // We need to clone the temporary identifier so that we can write it on a
                // new line
                expressions.push(node.multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
                return ts.inlineExpressions(expressions);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function shouldConvertIterationStatementBody(node) {
            return (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0;
        }
        /**
         * Records constituents of name for the given variable to be hoisted in the outer scope.
         */
        function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) {
            if (!state.hoistedLocalVariables) {
                state.hoistedLocalVariables = [];
            }
            visit(node.name);
            function visit(node) {
                if (node.kind === 71 /* Identifier */) {
                    state.hoistedLocalVariables.push(node);
                }
                else {
                    for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!ts.isOmittedExpression(element)) {
                            visit(element.name);
                        }
                    }
                }
            }
        }
        function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert) {
            if (!shouldConvertIterationStatementBody(node)) {
                var saveAllowedNonLabeledJumps = void 0;
                if (convertedLoopState) {
                    // we get here if we are trying to emit normal loop loop inside converted loop
                    // set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
                    saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                    convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */;
                }
                var result = convert
                    ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined)
                    : ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel);
                if (convertedLoopState) {
                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
                }
                return result;
            }
            var functionName = ts.createUniqueName("_loop");
            var loopInitializer;
            switch (node.kind) {
                case 214 /* ForStatement */:
                case 215 /* ForInStatement */:
                case 216 /* ForOfStatement */:
                    var initializer = node.initializer;
                    if (initializer && initializer.kind === 227 /* VariableDeclarationList */) {
                        loopInitializer = initializer;
                    }
                    break;
            }
            // variables that will be passed to the loop as parameters
            var loopParameters = [];
            // variables declared in the loop initializer that will be changed inside the loop
            var loopOutParameters = [];
            if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3 /* BlockScoped */)) {
                for (var _i = 0, _a = loopInitializer.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    processLoopVariableDeclaration(decl, loopParameters, loopOutParameters);
                }
            }
            var outerConvertedLoopState = convertedLoopState;
            convertedLoopState = { loopOutParameters: loopOutParameters };
            if (outerConvertedLoopState) {
                // convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
                // if outer converted loop has already accumulated some state - pass it through
                if (outerConvertedLoopState.argumentsName) {
                    // outer loop has already used 'arguments' so we've already have some name to alias it
                    // use the same name in all nested loops
                    convertedLoopState.argumentsName = outerConvertedLoopState.argumentsName;
                }
                if (outerConvertedLoopState.thisName) {
                    // outer loop has already used 'this' so we've already have some name to alias it
                    // use the same name in all nested loops
                    convertedLoopState.thisName = outerConvertedLoopState.thisName;
                }
                if (outerConvertedLoopState.hoistedLocalVariables) {
                    // we've already collected some non-block scoped variable declarations in enclosing loop
                    // use the same storage in nested loop
                    convertedLoopState.hoistedLocalVariables = outerConvertedLoopState.hoistedLocalVariables;
                }
            }
            startLexicalEnvironment();
            var loopBody = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
            var lexicalEnvironment = endLexicalEnvironment();
            var currentState = convertedLoopState;
            convertedLoopState = outerConvertedLoopState;
            if (loopOutParameters.length || lexicalEnvironment) {
                var statements_4 = ts.isBlock(loopBody) ? loopBody.statements.slice() : [loopBody];
                if (loopOutParameters.length) {
                    copyOutParameters(loopOutParameters, 1 /* ToOutParameter */, statements_4);
                }
                ts.addRange(statements_4, lexicalEnvironment);
                loopBody = ts.createBlock(statements_4, /*multiline*/ true);
            }
            if (ts.isBlock(loopBody)) {
                loopBody.multiLine = true;
            }
            else {
                loopBody = ts.createBlock([loopBody], /*multiline*/ true);
            }
            var containsYield = (node.statement.transformFlags & 16777216 /* ContainsYield */) !== 0;
            var isAsyncBlockContainingAwait = containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0;
            var loopBodyFlags = 0;
            if (currentState.containsLexicalThis) {
                loopBodyFlags |= 8 /* CapturesThis */;
            }
            if (isAsyncBlockContainingAwait) {
                loopBodyFlags |= 262144 /* AsyncFunctionBody */;
            }
            var convertedLoopVariable = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(39 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, loopParameters, 
                /*type*/ undefined, loopBody), loopBodyFlags))
            ]), 2097152 /* NoHoisting */));
            var statements = [convertedLoopVariable];
            var extraVariableDeclarations;
            // propagate state from the inner loop to the outer loop if necessary
            if (currentState.argumentsName) {
                // if alias for arguments is set
                if (outerConvertedLoopState) {
                    // pass it to outer converted loop
                    outerConvertedLoopState.argumentsName = currentState.argumentsName;
                }
                else {
                    // this is top level converted loop and we need to create an alias for 'arguments' object
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(currentState.argumentsName, 
                    /*type*/ undefined, ts.createIdentifier("arguments")));
                }
            }
            if (currentState.thisName) {
                // if alias for this is set
                if (outerConvertedLoopState) {
                    // pass it to outer converted loop
                    outerConvertedLoopState.thisName = currentState.thisName;
                }
                else {
                    // this is top level converted loop so we need to create an alias for 'this' here
                    // NOTE:
                    // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
                    // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(currentState.thisName, 
                    /*type*/ undefined, ts.createIdentifier("this")));
                }
            }
            if (currentState.hoistedLocalVariables) {
                // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
                if (outerConvertedLoopState) {
                    // pass them to outer converted loop
                    outerConvertedLoopState.hoistedLocalVariables = currentState.hoistedLocalVariables;
                }
                else {
                    if (!extraVariableDeclarations) {
                        extraVariableDeclarations = [];
                    }
                    // hoist collected variable declarations
                    for (var _b = 0, _c = currentState.hoistedLocalVariables; _b < _c.length; _b++) {
                        var identifier = _c[_b];
                        extraVariableDeclarations.push(ts.createVariableDeclaration(identifier));
                    }
                }
            }
            // add extra variables to hold out parameters if necessary
            if (loopOutParameters.length) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                for (var _d = 0, loopOutParameters_1 = loopOutParameters; _d < loopOutParameters_1.length; _d++) {
                    var outParam = loopOutParameters_1[_d];
                    extraVariableDeclarations.push(ts.createVariableDeclaration(outParam.outParamName));
                }
            }
            // create variable statement to hold all introduced variable declarations
            if (extraVariableDeclarations) {
                statements.push(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(extraVariableDeclarations)));
            }
            var convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, containsYield);
            var loop;
            if (convert) {
                loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
            }
            else {
                var clone_3 = ts.getMutableClone(node);
                // clean statement part
                clone_3.statement = undefined;
                // visit childnodes to transform initializer/condition/incrementor parts
                clone_3 = ts.visitEachChild(clone_3, visitor, context);
                // set loop statement
                clone_3.statement = ts.createBlock(convertedLoopBodyStatements, /*multiline*/ true);
                // reset and re-aggregate the transform flags
                clone_3.transformFlags = 0;
                ts.aggregateTransformFlags(clone_3);
                loop = ts.restoreEnclosingLabel(clone_3, outermostLabeledStatement, convertedLoopState && resetLabel);
            }
            statements.push(loop);
            return statements;
        }
        function copyOutParameter(outParam, copyDirection) {
            var source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName;
            var target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName;
            return ts.createBinary(target, 58 /* EqualsToken */, source);
        }
        function copyOutParameters(outParams, copyDirection, statements) {
            for (var _i = 0, outParams_1 = outParams; _i < outParams_1.length; _i++) {
                var outParam = outParams_1[_i];
                statements.push(ts.createStatement(copyOutParameter(outParam, copyDirection)));
            }
        }
        function generateCallToConvertedLoop(loopFunctionExpressionName, parameters, state, isAsyncBlockContainingAwait) {
            var outerConvertedLoopState = convertedLoopState;
            var statements = [];
            // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
            // simple loops are emitted as just 'loop()';
            // NOTE: if loop uses only 'continue' it still will be emitted as simple loop
            var isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) &&
                !state.labeledNonLocalBreaks &&
                !state.labeledNonLocalContinues;
            var call = ts.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, ts.map(parameters, function (p) { return p.name; }));
            var callResult = isAsyncBlockContainingAwait
                ? ts.createYield(ts.createToken(39 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            if (isSimpleLoop) {
                statements.push(ts.createStatement(callResult));
                copyOutParameters(state.loopOutParameters, 0 /* ToOriginal */, statements);
            }
            else {
                var loopResultName = ts.createUniqueName("state");
                var stateVariable = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)]));
                statements.push(stateVariable);
                copyOutParameters(state.loopOutParameters, 0 /* ToOriginal */, statements);
                if (state.nonLocalJumps & 8 /* Return */) {
                    var returnStatement = void 0;
                    if (outerConvertedLoopState) {
                        outerConvertedLoopState.nonLocalJumps |= 8 /* Return */;
                        returnStatement = ts.createReturn(loopResultName);
                    }
                    else {
                        returnStatement = ts.createReturn(ts.createPropertyAccess(loopResultName, "value"));
                    }
                    statements.push(ts.createIf(ts.createBinary(ts.createTypeOf(loopResultName), 34 /* EqualsEqualsEqualsToken */, ts.createLiteral("object")), returnStatement));
                }
                if (state.nonLocalJumps & 2 /* Break */) {
                    statements.push(ts.createIf(ts.createBinary(loopResultName, 34 /* EqualsEqualsEqualsToken */, ts.createLiteral("break")), ts.createBreak()));
                }
                if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
                    var caseClauses = [];
                    processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
                    processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
                    statements.push(ts.createSwitch(loopResultName, ts.createCaseBlock(caseClauses)));
                }
            }
            return statements;
        }
        function setLabeledJump(state, isBreak, labelText, labelMarker) {
            if (isBreak) {
                if (!state.labeledNonLocalBreaks) {
                    state.labeledNonLocalBreaks = ts.createMap();
                }
                state.labeledNonLocalBreaks.set(labelText, labelMarker);
            }
            else {
                if (!state.labeledNonLocalContinues) {
                    state.labeledNonLocalContinues = ts.createMap();
                }
                state.labeledNonLocalContinues.set(labelText, labelMarker);
            }
        }
        function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) {
            if (!table) {
                return;
            }
            table.forEach(function (labelMarker, labelText) {
                var statements = [];
                // if there are no outer converted loop or outer label in question is located inside outer converted loop
                // then emit labeled break\continue
                // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
                if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) {
                    var label = ts.createIdentifier(labelText);
                    statements.push(isBreak ? ts.createBreak(label) : ts.createContinue(label));
                }
                else {
                    setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
                    statements.push(ts.createReturn(loopResultName));
                }
                caseClauses.push(ts.createCaseClause(ts.createLiteral(labelMarker), statements));
            });
        }
        function processLoopVariableDeclaration(decl, loopParameters, loopOutParameters) {
            var name = decl.name;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
                    }
                }
            }
            else {
                loopParameters.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
                if (resolver.getNodeCheckFlags(decl) & 2097152 /* NeedsLoopOutParameter */) {
                    var outParamName = ts.createUniqueName("out_" + ts.idText(name));
                    loopOutParameters.push({ originalName: name, outParamName: outParamName });
                }
            }
        }
        /**
         * Adds the members of an object literal to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node An ObjectLiteralExpression node.
         * @param receiver The receiver for members of the ObjectLiteralExpression.
         * @param numInitialNonComputedProperties The number of initial properties without
         *                                        computed property names.
         */
        function addObjectLiteralMembers(expressions, node, receiver, start) {
            var properties = node.properties;
            var numProperties = properties.length;
            for (var i = start; i < numProperties; i++) {
                var property = properties[i];
                switch (property.kind) {
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.properties, property);
                        if (property === accessors.firstAccessor) {
                            expressions.push(transformAccessorsToExpression(receiver, accessors, node, node.multiLine));
                        }
                        break;
                    case 151 /* MethodDeclaration */:
                        expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
                        break;
                    case 261 /* PropertyAssignment */:
                        expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    case 262 /* ShorthandPropertyAssignment */:
                        expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
            }
        }
        /**
         * Transforms a PropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the PropertyAssignment.
         * @param property The PropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.visitNode(property.initializer, visitor, ts.isExpression));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                expression.startsOnNewLine = true;
            }
            return expression;
        }
        /**
         * Transforms a ShorthandPropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the ShorthandPropertyAssignment.
         * @param property The ShorthandPropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.getSynthesizedClone(property.name));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                expression.startsOnNewLine = true;
            }
            return expression;
        }
        /**
         * Transforms a MethodDeclaration of an ObjectLiteralExpression into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the MethodDeclaration.
         * @param method The MethodDeclaration node.
         * @param receiver The receiver for the assignment.
         */
        function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) {
            var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */);
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(method.name, visitor, ts.isPropertyName)), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container));
            ts.setTextRange(expression, method);
            if (startsOnNewLine) {
                expression.startsOnNewLine = true;
            }
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */);
            return expression;
        }
        function visitCatchClause(node) {
            var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated;
            ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
            if (ts.isBindingPattern(node.variableDeclaration.name)) {
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var newVariableDeclaration = ts.createVariableDeclaration(temp);
                ts.setTextRange(newVariableDeclaration, node.variableDeclaration);
                var vars = ts.flattenDestructuringBinding(node.variableDeclaration, visitor, context, 0 /* All */, temp);
                var list = ts.createVariableDeclarationList(vars);
                ts.setTextRange(list, node.variableDeclaration);
                var destructure = ts.createVariableStatement(/*modifiers*/ undefined, list);
                updated = ts.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function addStatementToStartOfBlock(block, statement) {
            var transformedStatements = ts.visitNodes(block.statements, visitor, ts.isStatement);
            return ts.updateBlock(block, [statement].concat(transformedStatements));
        }
        /**
         * Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
         * PropertyAssignment.
         *
         * @param node A MethodDeclaration node.
         */
        function visitMethodDeclaration(node) {
            // We should only get here for methods on an object literal with regular identifier names.
            // Methods on classes are handled in visitClassDeclaration/visitClassExpression.
            // Methods with computed property names are handled in visitObjectLiteralExpression.
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var functionExpression = transformFunctionLikeToExpression(node, /*location*/ ts.moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
            ts.setEmitFlags(functionExpression, 512 /* NoLeadingComments */ | ts.getEmitFlags(functionExpression));
            return ts.setTextRange(ts.createPropertyAssignment(node.name, functionExpression), 
            /*location*/ node);
        }
        /**
         * Visits an AccessorDeclaration of an ObjectLiteralExpression.
         *
         * @param node An AccessorDeclaration node.
         */
        function visitAccessorDeclaration(node) {
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var updated;
            if (node.transformFlags & 32768 /* ContainsCapturedLexicalThis */) {
                var parameters = ts.visitParameterList(node.parameters, visitor, context);
                var body = transformFunctionBody(node);
                if (node.kind === 153 /* GetAccessor */) {
                    updated = ts.updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
                }
                else {
                    updated = ts.updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
                }
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return updated;
        }
        /**
         * Visits a ShorthandPropertyAssignment and transforms it into a PropertyAssignment.
         *
         * @param node A ShorthandPropertyAssignment node.
         */
        function visitShorthandPropertyAssignment(node) {
            return ts.setTextRange(ts.createPropertyAssignment(node.name, ts.getSynthesizedClone(node.name)), 
            /*location*/ node);
        }
        function visitComputedPropertyName(node) {
            var ancestorFacts = enterSubtree(0 /* ComputedPropertyNameExcludes */, 8192 /* ComputedPropertyNameIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 32768 /* NewTargetInComputedPropertyName */ : 0 /* None */);
            return updated;
        }
        /**
         * Visits a YieldExpression node.
         *
         * @param node A YieldExpression node.
         */
        function visitYieldExpression(node) {
            // `yield` expressions are transformed using the generators transformer.
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a spread element.
         *
         * @param node An ArrayLiteralExpression node.
         */
        function visitArrayLiteralExpression(node) {
            if (node.transformFlags & 64 /* ES2015 */) {
                // We are here because we contain a SpreadElementExpression.
                return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, node.multiLine, /*hasTrailingComma*/ node.elements.hasTrailingComma);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a CallExpression that contains either a spread element or `super`.
         *
         * @param node a CallExpression.
         */
        function visitCallExpression(node) {
            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
                return visitTypeScriptClassWrapper(node);
            }
            if (node.transformFlags & 64 /* ES2015 */) {
                return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
            }
            return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTypeScriptClassWrapper(node) {
            // This is a call to a class wrapper function (an IIFE) created by the 'ts' transformer.
            // The wrapper has a form similar to:
            //
            //  (function() {
            //      class C { // 1
            //      }
            //      C.x = 1; // 2
            //      return C;
            //  }())
            //
            // When we transform the class, we end up with something like this:
            //
            //  (function () {
            //      var C = (function () { // 3
            //          function C() {
            //          }
            //          return C; // 4
            //      }());
            //      C.x = 1;
            //      return C;
            //  }())
            //
            // We want to simplify the two nested IIFEs to end up with something like this:
            //
            //  (function () {
            //      function C() {
            //      }
            //      C.x = 1;
            //      return C;
            //  }())
            // We skip any outer expressions in a number of places to get to the innermost
            // expression, but we will restore them later to preserve comments and source maps.
            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
            // The class statements are the statements generated by visiting the first statement of the
            // body (1), while all other statements are added to remainingStatements (2)
            var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1);
            var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1);
            var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement);
            // We know there is only one variable declaration here as we verified this in an
            // earlier call to isTypeScriptClassWrapper
            var variable = varStatement.declarationList.declarations[0];
            var initializer = ts.skipOuterExpressions(variable.initializer);
            // Under certain conditions, the 'ts' transformer may introduce a class alias, which
            // we see as an assignment, for example:
            //
            //  (function () {
            //      var C = C_1 = (function () {
            //          function C() {
            //          }
            //          C.x = function () { return C_1; }
            //          return C;
            //      }());
            //      C = C_1 = __decorate([dec], C);
            //      return C;
            //      var C_1;
            //  }())
            //
            var aliasAssignment = ts.tryCast(initializer, ts.isAssignmentExpression);
            // The underlying call (3) is another IIFE that may contain a '_super' argument.
            var call = ts.cast(aliasAssignment ? ts.skipOuterExpressions(aliasAssignment.right) : initializer, ts.isCallExpression);
            var func = ts.cast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
            var funcStatements = func.body.statements;
            var classBodyStart = 0;
            var classBodyEnd = -1;
            var statements = [];
            if (aliasAssignment) {
                // If we have a class alias assignment, we need to move it to the down-level constructor
                // function we generated for the class.
                var extendsCall = ts.tryCast(funcStatements[classBodyStart], ts.isExpressionStatement);
                if (extendsCall) {
                    statements.push(extendsCall);
                    classBodyStart++;
                }
                // The next statement is the function declaration.
                statements.push(funcStatements[classBodyStart]);
                classBodyStart++;
                // Add the class alias following the declaration.
                statements.push(ts.createStatement(ts.createAssignment(aliasAssignment.left, ts.cast(variable.name, ts.isIdentifier))));
            }
            // Find the trailing 'return' statement (4)
            while (!ts.isReturnStatement(ts.elementAt(funcStatements, classBodyEnd))) {
                classBodyEnd--;
            }
            // When we extract the statements of the inner IIFE, we exclude the 'return' statement (4)
            // as we already have one that has been introduced by the 'ts' transformer.
            ts.addRange(statements, funcStatements, classBodyStart, classBodyEnd);
            if (classBodyEnd < -1) {
                // If there were any hoisted declarations following the return statement, we should
                // append them.
                ts.addRange(statements, funcStatements, classBodyEnd + 1);
            }
            // Add the remaining statements of the outer wrapper.
            ts.addRange(statements, remainingStatements);
            // The 'es2015' class transform may add an end-of-declaration marker. If so we will add it
            // after the remaining statements from the 'ts' transformer.
            ts.addRange(statements, classStatements, /*start*/ 1);
            // Recreate any outer parentheses or partially-emitted expressions to preserve source map
            // and comment locations.
            return ts.recreateOuterExpressions(node.expression, ts.recreateOuterExpressions(variable.initializer, ts.recreateOuterExpressions(aliasAssignment && aliasAssignment.right, ts.updateCall(call, ts.recreateOuterExpressions(call.expression, ts.updateFunctionExpression(func, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, func.parameters, 
            /*type*/ undefined, ts.updateBlock(func.body, statements))), 
            /*typeArguments*/ undefined, call.arguments))));
        }
        function visitImmediateSuperCallInBody(node) {
            return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ false);
        }
        function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) {
            // We are here either because SuperKeyword was used somewhere in the expression, or
            // because we contain a SpreadElementExpression.
            var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
            if (node.expression.kind === 97 /* SuperKeyword */) {
                ts.setEmitFlags(thisArg, 4 /* NoSubstitution */);
            }
            var resultingCall;
            if (node.transformFlags & 524288 /* ContainsSpread */) {
                // [source]
                //      f(...a, b)
                //      x.m(...a, b)
                //      super(...a, b)
                //      super.m(...a, b) // in static
                //      super.m(...a, b) // in instance
                //
                // [output]
                //      f.apply(void 0, a.concat([b]))
                //      (_a = x).m.apply(_a, a.concat([b]))
                //      _super.apply(this, a.concat([b]))
                //      _super.m.apply(this, a.concat([b]))
                //      _super.prototype.m.apply(this, a.concat([b]))
                resultingCall = ts.createFunctionApply(ts.visitNode(target, callExpressionVisitor, ts.isExpression), ts.visitNode(thisArg, visitor, ts.isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false));
            }
            else {
                // [source]
                //      super(a)
                //      super.m(a) // in static
                //      super.m(a) // in instance
                //
                // [output]
                //      _super.call(this, a)
                //      _super.m.call(this, a)
                //      _super.prototype.m.call(this, a)
                resultingCall = ts.createFunctionCall(ts.visitNode(target, callExpressionVisitor, ts.isExpression), ts.visitNode(thisArg, visitor, ts.isExpression), ts.visitNodes(node.arguments, visitor, ts.isExpression), 
                /*location*/ node);
            }
            if (node.expression.kind === 97 /* SuperKeyword */) {
                var actualThis = ts.createThis();
                ts.setEmitFlags(actualThis, 4 /* NoSubstitution */);
                var initializer = ts.createLogicalOr(resultingCall, actualThis);
                resultingCall = assignToCapturedThis
                    ? ts.createAssignment(ts.createIdentifier("_this"), initializer)
                    : initializer;
            }
            return ts.setOriginalNode(resultingCall, node);
        }
        /**
         * Visits a NewExpression that contains a spread element.
         *
         * @param node A NewExpression node.
         */
        function visitNewExpression(node) {
            if (node.transformFlags & 524288 /* ContainsSpread */) {
                // We are here because we contain a SpreadElementExpression.
                // [source]
                //      new C(...a)
                //
                // [output]
                //      new ((_a = C).bind.apply(_a, [void 0].concat(a)))()
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.createNew(ts.createFunctionApply(ts.visitNode(target, visitor, ts.isExpression), thisArg, transformAndSpreadElements(ts.createNodeArray([ts.createVoidZero()].concat(node.arguments)), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)), 
                /*typeArguments*/ undefined, []);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an array of Expression nodes that contains a SpreadExpression.
         *
         * @param elements The array of Expression nodes.
         * @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
         * @param multiLine A value indicating whether the result should be emitted on multiple lines.
         */
        function transformAndSpreadElements(elements, needsUniqueCopy, multiLine, hasTrailingComma) {
            // [source]
            //      [a, ...b, c]
            //
            // [output]
            //      [a].concat(b, [c])
            // Map spans of spread expressions into their expressions and spans of other
            // expressions into an array literal.
            var numElements = elements.length;
            var segments = ts.flatten(ts.spanMap(elements, partitionSpread, function (partition, visitPartition, _start, end) {
                return visitPartition(partition, multiLine, hasTrailingComma && end === numElements);
            }));
            if (compilerOptions.downlevelIteration) {
                if (segments.length === 1) {
                    var firstSegment = segments[0];
                    if (ts.isCallExpression(firstSegment)
                        && ts.isIdentifier(firstSegment.expression)
                        && (ts.getEmitFlags(firstSegment.expression) & 4096 /* HelperName */)
                        && firstSegment.expression.escapedText === "___spread") {
                        return segments[0];
                    }
                }
                return ts.createSpreadHelper(context, segments);
            }
            else {
                if (segments.length === 1) {
                    var firstElement = elements[0];
                    return needsUniqueCopy && ts.isSpreadElement(firstElement) && firstElement.expression.kind !== 177 /* ArrayLiteralExpression */
                        ? ts.createArraySlice(segments[0])
                        : segments[0];
                }
                // Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
                return ts.createArrayConcat(segments.shift(), segments);
            }
        }
        function partitionSpread(node) {
            return ts.isSpreadElement(node)
                ? visitSpanOfSpreads
                : visitSpanOfNonSpreads;
        }
        function visitSpanOfSpreads(chunk) {
            return ts.map(chunk, visitExpressionOfSpread);
        }
        function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) {
            return ts.createArrayLiteral(ts.visitNodes(ts.createNodeArray(chunk, hasTrailingComma), visitor, ts.isExpression), multiLine);
        }
        function visitSpreadElement(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the expression of a SpreadExpression node.
         *
         * @param node A SpreadExpression node.
         */
        function visitExpressionOfSpread(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Visits a template literal.
         *
         * @param node A template literal.
         */
        function visitTemplateLiteral(node) {
            return ts.setTextRange(ts.createLiteral(node.text), node);
        }
        /**
         * Visits a string literal with an extended unicode escape.
         *
         * @param node A string literal.
         */
        function visitStringLiteral(node) {
            if (node.hasExtendedUnicodeEscape) {
                return ts.setTextRange(ts.createLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a binary or octal (ES6) numeric literal.
         *
         * @param node A string literal.
         */
        function visitNumericLiteral(node) {
            if (node.numericLiteralFlags & 48 /* BinaryOrOctalSpecifier */) {
                return ts.setTextRange(ts.createNumericLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a TaggedTemplateExpression node.
         *
         * @param node A TaggedTemplateExpression node.
         */
        function visitTaggedTemplateExpression(node) {
            // Visit the tag expression
            var tag = ts.visitNode(node.tag, visitor, ts.isExpression);
            // Build up the template arguments and the raw and cooked strings for the template.
            // We start out with 'undefined' for the first argument and revisit later
            // to avoid walking over the template string twice and shifting all our arguments over after the fact.
            var templateArguments = [undefined];
            var cookedStrings = [];
            var rawStrings = [];
            var template = node.template;
            if (ts.isNoSubstitutionTemplateLiteral(template)) {
                cookedStrings.push(ts.createLiteral(template.text));
                rawStrings.push(getRawLiteral(template));
            }
            else {
                cookedStrings.push(ts.createLiteral(template.head.text));
                rawStrings.push(getRawLiteral(template.head));
                for (var _i = 0, _a = template.templateSpans; _i < _a.length; _i++) {
                    var templateSpan = _a[_i];
                    cookedStrings.push(ts.createLiteral(templateSpan.literal.text));
                    rawStrings.push(getRawLiteral(templateSpan.literal));
                    templateArguments.push(ts.visitNode(templateSpan.expression, visitor, ts.isExpression));
                }
            }
            var helperCall = createTemplateObjectHelper(context, ts.createArrayLiteral(cookedStrings), ts.createArrayLiteral(rawStrings));
            // Create a variable to cache the template object if we're in a module.
            // Do not do this in the global scope, as any variable we currently generate could conflict with
            // variables from outside of the current compilation. In the future, we can revisit this behavior.
            if (ts.isExternalModule(currentSourceFile)) {
                var tempVar = ts.createUniqueName("templateObject");
                recordTaggedTemplateString(tempVar);
                templateArguments[0] = ts.createLogicalOr(tempVar, ts.createAssignment(tempVar, helperCall));
            }
            else {
                templateArguments[0] = helperCall;
            }
            return ts.createCall(tag, /*typeArguments*/ undefined, templateArguments);
        }
        /**
         * Creates an ES5 compatible literal from an ES6 template literal.
         *
         * @param node The ES6 template literal.
         */
        function getRawLiteral(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 === 13 /* NoSubstitutionTemplateLiteral */ || node.kind === 16 /* 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
            // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
            text = text.replace(/\r\n?/g, "\n");
            return ts.setTextRange(ts.createLiteral(text), node);
        }
        /**
         * Visits a TemplateExpression node.
         *
         * @param node A TemplateExpression node.
         */
        function visitTemplateExpression(node) {
            var expressions = [];
            addTemplateHead(expressions, node);
            addTemplateSpans(expressions, node);
            // createAdd will check if each expression binds less closely than binary '+'.
            // If it does, it wraps 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 expression = ts.reduceLeft(expressions, ts.createAdd);
            if (ts.nodeIsSynthesized(expression)) {
                expression.pos = node.pos;
                expression.end = node.end;
            }
            return expression;
        }
        /**
         * Gets a value indicating whether we need to include the head of a TemplateExpression.
         *
         * @param node A TemplateExpression node.
         */
        function shouldAddTemplateHead(node) {
            // 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;
        }
        /**
         * Adds the head of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateHead(expressions, node) {
            if (!shouldAddTemplateHead(node)) {
                return;
            }
            expressions.push(ts.createLiteral(node.head.text));
        }
        /**
         * Visits and adds the template spans of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateSpans(expressions, node) {
            for (var _i = 0, _a = node.templateSpans; _i < _a.length; _i++) {
                var span_6 = _a[_i];
                expressions.push(ts.visitNode(span_6.expression, visitor, ts.isExpression));
                // 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 (span_6.literal.text.length !== 0) {
                    expressions.push(ts.createLiteral(span_6.literal.text));
                }
            }
        }
        /**
         * Visits the `super` keyword
         */
        function visitSuperKeyword(isExpressionOfCall) {
            return hierarchyFacts & 8 /* NonStaticClassElement */
                && !isExpressionOfCall
                ? ts.createPropertyAccess(ts.createIdentifier("_super"), "prototype")
                : ts.createIdentifier("_super");
        }
        function visitMetaProperty(node) {
            if (node.keywordToken === 94 /* NewKeyword */ && node.name.escapedText === "target") {
                if (hierarchyFacts & 8192 /* ComputedPropertyName */) {
                    hierarchyFacts |= 32768 /* NewTargetInComputedPropertyName */;
                }
                else {
                    hierarchyFacts |= 16384 /* NewTarget */;
                }
                return ts.createIdentifier("_newTarget");
            }
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (enabledSubstitutions & 1 /* CapturedThis */ && ts.isFunctionLike(node)) {
                // If we are tracking a captured `this`, keep track of the enclosing function.
                var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, ts.getEmitFlags(node) & 8 /* CapturesThis */
                    ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */
                    : 65 /* FunctionIncludes */);
                previousOnEmitNode(hint, node, emitCallback);
                exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains block-scoped bindings (e.g. `let` or `const`).
         */
        function enableSubstitutionsForBlockScopedBindings() {
            if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) {
                enabledSubstitutions |= 2 /* BlockScopedBindings */;
                context.enableSubstitution(71 /* Identifier */);
            }
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains a captured `this`.
         */
        function enableSubstitutionsForCapturedThis() {
            if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) {
                enabledSubstitutions |= 1 /* CapturedThis */;
                context.enableSubstitution(99 /* ThisKeyword */);
                context.enableEmitNotification(152 /* Constructor */);
                context.enableEmitNotification(151 /* MethodDeclaration */);
                context.enableEmitNotification(153 /* GetAccessor */);
                context.enableEmitNotification(154 /* SetAccessor */);
                context.enableEmitNotification(187 /* ArrowFunction */);
                context.enableEmitNotification(186 /* FunctionExpression */);
                context.enableEmitNotification(228 /* FunctionDeclaration */);
            }
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            if (ts.isIdentifier(node)) {
                return substituteIdentifier(node);
            }
            return node;
        }
        /**
         * Hooks substitutions for non-expression identifiers.
         */
        function substituteIdentifier(node) {
            // Only substitute the identifier if we have enabled substitutions for block-scoped
            // bindings.
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var original = ts.getParseTreeNode(node, ts.isIdentifier);
                if (original && isNameOfDeclarationWithCollidingName(original)) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(original), node);
                }
            }
            return node;
        }
        /**
         * Determines whether a name is the name of a declaration with a colliding name.
         * NOTE: This function expects to be called with an original source tree node.
         *
         * @param node An original source tree node.
         */
        function isNameOfDeclarationWithCollidingName(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 176 /* BindingElement */:
                case 229 /* ClassDeclaration */:
                case 232 /* EnumDeclaration */:
                case 226 /* VariableDeclaration */:
                    return parent.name === node
                        && resolver.isDeclarationWithCollidingName(parent);
            }
            return false;
        }
        /**
         * Substitutes an expression.
         *
         * @param node An Expression node.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 99 /* ThisKeyword */:
                    return substituteThisKeyword(node);
            }
            return node;
        }
        /**
         * Substitutes an expression identifier.
         *
         * @param node An Identifier node.
         */
        function substituteExpressionIdentifier(node) {
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var declaration = resolver.getReferencedDeclarationWithCollidingName(node);
                if (declaration && !(ts.isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(ts.getNameOfDeclaration(declaration)), node);
                }
            }
            return node;
        }
        function isPartOfClassBody(declaration, node) {
            var currentNode = ts.getParseTreeNode(node);
            if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
                // if the node has no correlation to a parse tree node, its definitely not
                // part of the body.
                // if the node is outside of the document range of the declaration, its
                // definitely not part of the body.
                return false;
            }
            var blockScope = ts.getEnclosingBlockScopeContainer(declaration);
            while (currentNode) {
                if (currentNode === blockScope || currentNode === declaration) {
                    // if we are in the enclosing block scope of the declaration, we are definitely
                    // not inside the class body.
                    return false;
                }
                if (ts.isClassElement(currentNode) && currentNode.parent === declaration) {
                    return true;
                }
                currentNode = currentNode.parent;
            }
            return false;
        }
        /**
         * Substitutes `this` when contained within an arrow function.
         *
         * @param node The ThisKeyword node.
         */
        function substituteThisKeyword(node) {
            if (enabledSubstitutions & 1 /* CapturedThis */
                && hierarchyFacts & 16 /* CapturesThis */) {
                return ts.setTextRange(ts.createIdentifier("_this"), node);
            }
            return node;
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getInternalName(node)
                : ts.createPropertyAccess(ts.getInternalName(node), "prototype");
        }
        function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) {
            if (!constructor || !hasExtendsClause) {
                return false;
            }
            if (ts.some(constructor.parameters)) {
                return false;
            }
            var statement = ts.firstOrUndefined(constructor.body.statements);
            if (!statement || !ts.nodeIsSynthesized(statement) || statement.kind !== 210 /* ExpressionStatement */) {
                return false;
            }
            var statementExpression = statement.expression;
            if (!ts.nodeIsSynthesized(statementExpression) || statementExpression.kind !== 181 /* CallExpression */) {
                return false;
            }
            var callTarget = statementExpression.expression;
            if (!ts.nodeIsSynthesized(callTarget) || callTarget.kind !== 97 /* SuperKeyword */) {
                return false;
            }
            var callArgument = ts.singleOrUndefined(statementExpression.arguments);
            if (!callArgument || !ts.nodeIsSynthesized(callArgument) || callArgument.kind !== 198 /* SpreadElement */) {
                return false;
            }
            var expression = callArgument.expression;
            return ts.isIdentifier(expression) && expression.escapedText === "arguments";
        }
    }
    ts.transformES2015 = transformES2015;
    function createExtendsHelper(context, name) {
        context.requestEmitHelper(extendsHelper);
        return ts.createCall(ts.getHelperName("__extends"), 
        /*typeArguments*/ undefined, [
            name,
            ts.createIdentifier("_super")
        ]);
    }
    function createTemplateObjectHelper(context, cooked, raw) {
        context.requestEmitHelper(templateObjectHelper);
        return ts.createCall(ts.getHelperName("__makeTemplateObject"), 
        /*typeArguments*/ undefined, [
            cooked,
            raw
        ]);
    }
    var extendsHelper = {
        name: "typescript:extends",
        scoped: false,
        priority: 0,
        text: "\n            var __extends = (this && this.__extends) || (function () {\n                var extendStatics = Object.setPrototypeOf ||\n                    ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n                    function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n                return function (d, b) {\n                    extendStatics(d, b);\n                    function __() { this.constructor = d; }\n                    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n                };\n            })();"
    };
    var templateObjectHelper = {
        name: "typescript:makeTemplateObject",
        scoped: false,
        priority: 0,
        text: "\n            var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n                if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n                return cooked;\n            };"
    };
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
var ts;
(function (ts) {
    /**
     * Transforms ES5 syntax into ES3 syntax.
     *
     * @param context Context and state information for the transformation.
     */
    function transformES5(context) {
        var compilerOptions = context.getCompilerOptions();
        // enable emit notification only if using --jsx preserve or react-native
        var previousOnEmitNode;
        var noSubstitution;
        if (compilerOptions.jsx === 1 /* Preserve */ || compilerOptions.jsx === 3 /* ReactNative */) {
            previousOnEmitNode = context.onEmitNode;
            context.onEmitNode = onEmitNode;
            context.enableEmitNotification(251 /* JsxOpeningElement */);
            context.enableEmitNotification(252 /* JsxClosingElement */);
            context.enableEmitNotification(250 /* JsxSelfClosingElement */);
            noSubstitution = [];
        }
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableSubstitution(179 /* PropertyAccessExpression */);
        context.enableSubstitution(261 /* PropertyAssignment */);
        return transformSourceFile;
        /**
         * Transforms an ES5 source file to ES3.
         *
         * @param node A SourceFile
         */
        function transformSourceFile(node) {
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            switch (node.kind) {
                case 251 /* JsxOpeningElement */:
                case 252 /* JsxClosingElement */:
                case 250 /* JsxSelfClosingElement */:
                    var tagName = node.tagName;
                    noSubstitution[ts.getOriginalNodeId(tagName)] = true;
                    break;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            if (node.id && noSubstitution && noSubstitution[node.id]) {
                return previousOnSubstituteNode(hint, node);
            }
            node = previousOnSubstituteNode(hint, node);
            if (ts.isPropertyAccessExpression(node)) {
                return substitutePropertyAccessExpression(node);
            }
            else if (ts.isPropertyAssignment(node)) {
                return substitutePropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAccessExpression whose name is a reserved word.
         *
         * @param node A PropertyAccessExpression
         */
        function substitutePropertyAccessExpression(node) {
            var literalName = trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.setTextRange(ts.createElementAccess(node.expression, literalName), node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAssignment whose name is a reserved word.
         *
         * @param node A PropertyAssignment
         */
        function substitutePropertyAssignment(node) {
            var literalName = ts.isIdentifier(node.name) && trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.updatePropertyAssignment(node, literalName, node.initializer);
            }
            return node;
        }
        /**
         * If an identifier name is a reserved word, returns a string literal for the name.
         *
         * @param name An Identifier
         */
        function trySubstituteReservedName(name) {
            var token = name.originalKeywordKind || (ts.nodeIsSynthesized(name) ? ts.stringToToken(ts.idText(name)) : undefined);
            if (token >= 72 /* FirstReservedWord */ && token <= 107 /* LastReservedWord */) {
                return ts.setTextRange(ts.createLiteral(name), name);
            }
            return undefined;
        }
    }
    ts.transformES5 = transformES5;
})(ts || (ts = {}));
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
// Transforms generator functions into a compatible ES5 representation with similar runtime
// semantics. This is accomplished by first transforming the body of each generator
// function into an intermediate representation that is the compiled into a JavaScript
// switch statement.
//
// Many functions in this transformer will contain comments indicating the expected
// intermediate representation. For illustrative purposes, the following intermediate
// language is used to define this intermediate representation:
//
//  .nop                            - Performs no operation.
//  .local NAME, ...                - Define local variable declarations.
//  .mark LABEL                     - Mark the location of a label.
//  .br LABEL                       - Jump to a label. If jumping out of a protected
//                                    region, all .finally blocks are executed.
//  .brtrue LABEL, (x)              - Jump to a label IIF the expression `x` is truthy.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .brfalse LABEL, (x)             - Jump to a label IIF the expression `x` is falsey.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .yield (x)                      - Yield the value of the optional expression `x`.
//                                    Resume at the next label.
//  .yieldstar (x)                  - Delegate yield to the value of the optional
//                                    expression `x`. Resume at the next label.
//                                    NOTE: `x` must be an Iterator, not an Iterable.
//  .loop CONTINUE, BREAK           - Marks the beginning of a loop. Any "continue" or
//                                    "break" abrupt completions jump to the CONTINUE or
//                                    BREAK labels, respectively.
//  .endloop                        - Marks the end of a loop.
//  .with (x)                       - Marks the beginning of a WithStatement block, using
//                                    the supplied expression.
//  .endwith                        - Marks the end of a WithStatement.
//  .switch                         - Marks the beginning of a SwitchStatement.
//  .endswitch                      - Marks the end of a SwitchStatement.
//  .labeled NAME                   - Marks the beginning of a LabeledStatement with the
//                                    supplied name.
//  .endlabeled                     - Marks the end of a LabeledStatement.
//  .try TRY, CATCH, FINALLY, END   - Marks the beginning of a protected region, and the
//                                    labels for each block.
//  .catch (x)                      - Marks the beginning of a catch block.
//  .finally                        - Marks the beginning of a finally block.
//  .endfinally                     - Marks the end of a finally block.
//  .endtry                         - Marks the end of a protected region.
//  .throw (x)                      - Throws the value of the expression `x`.
//  .return (x)                     - Returns the value of the expression `x`.
//
// In addition, the illustrative intermediate representation introduces some special
// variables:
//
//  %sent%                          - Either returns the next value sent to the generator,
//                                    returns the result of a delegated yield, or throws
//                                    the exception sent to the generator.
//  %error%                         - Returns the value of the current exception in a
//                                    catch block.
//
// This intermediate representation is then compiled into JavaScript syntax. The resulting
// compilation output looks something like the following:
//
//  function f() {
//      var /*locals*/;
//      /*functions*/
//      return __generator(function (state) {
//          switch (state.label) {
//              /*cases per label*/
//          }
//      });
//  }
//
// Each of the above instructions corresponds to JavaScript emit similar to the following:
//
//  .local NAME                   | var NAME;
// -------------------------------|----------------------------------------------
//  .mark LABEL                   | case LABEL:
// -------------------------------|----------------------------------------------
//  .br LABEL                     |     return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brtrue LABEL, (x)            |     if (x) return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brfalse LABEL, (x)           |     if (!(x)) return [3, /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .yield (x)                    |     return [4 /*yield*/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .yieldstar (x)                |     return [5 /*yield**/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .with (_a)                    |     with (_a) {
//      a();                      |         a();
//                                |     }
//                                |     state.label = LABEL;
//  .mark LABEL                   | case LABEL:
//                                |     with (_a) {
//      b();                      |         b();
//                                |     }
//  .endwith                      |
// -------------------------------|----------------------------------------------
//                                | case 0:
//                                |     state.trys = [];
//                                | ...
//  .try TRY, CATCH, FINALLY, END |
//  .mark TRY                     | case TRY:
//                                |     state.trys.push([TRY, CATCH, FINALLY, END]);
//  .nop                          |
//      a();                      |     a();
//  .br END                       |     return [3 /*break*/, END];
//  .catch (e)                    |
//  .mark CATCH                   | case CATCH:
//                                |     e = state.sent();
//      b();                      |     b();
//  .br END                       |     return [3 /*break*/, END];
//  .finally                      |
//  .mark FINALLY                 | case FINALLY:
//      c();                      |     c();
//  .endfinally                   |     return [7 /*endfinally*/];
//  .endtry                       |
//  .mark END                     | case END:
/*@internal*/
var ts;
(function (ts) {
    var OpCode;
    (function (OpCode) {
        OpCode[OpCode["Nop"] = 0] = "Nop";
        OpCode[OpCode["Statement"] = 1] = "Statement";
        OpCode[OpCode["Assign"] = 2] = "Assign";
        OpCode[OpCode["Break"] = 3] = "Break";
        OpCode[OpCode["BreakWhenTrue"] = 4] = "BreakWhenTrue";
        OpCode[OpCode["BreakWhenFalse"] = 5] = "BreakWhenFalse";
        OpCode[OpCode["Yield"] = 6] = "Yield";
        OpCode[OpCode["YieldStar"] = 7] = "YieldStar";
        OpCode[OpCode["Return"] = 8] = "Return";
        OpCode[OpCode["Throw"] = 9] = "Throw";
        OpCode[OpCode["Endfinally"] = 10] = "Endfinally"; // Marks the end of a `finally` block
    })(OpCode || (OpCode = {}));
    // whether a generated code block is opening or closing at the current operation for a FunctionBuilder
    var BlockAction;
    (function (BlockAction) {
        BlockAction[BlockAction["Open"] = 0] = "Open";
        BlockAction[BlockAction["Close"] = 1] = "Close";
    })(BlockAction || (BlockAction = {}));
    // the kind for a generated code block in a FunctionBuilder
    var CodeBlockKind;
    (function (CodeBlockKind) {
        CodeBlockKind[CodeBlockKind["Exception"] = 0] = "Exception";
        CodeBlockKind[CodeBlockKind["With"] = 1] = "With";
        CodeBlockKind[CodeBlockKind["Switch"] = 2] = "Switch";
        CodeBlockKind[CodeBlockKind["Loop"] = 3] = "Loop";
        CodeBlockKind[CodeBlockKind["Labeled"] = 4] = "Labeled";
    })(CodeBlockKind || (CodeBlockKind = {}));
    // the state for a generated code exception block
    var ExceptionBlockState;
    (function (ExceptionBlockState) {
        ExceptionBlockState[ExceptionBlockState["Try"] = 0] = "Try";
        ExceptionBlockState[ExceptionBlockState["Catch"] = 1] = "Catch";
        ExceptionBlockState[ExceptionBlockState["Finally"] = 2] = "Finally";
        ExceptionBlockState[ExceptionBlockState["Done"] = 3] = "Done";
    })(ExceptionBlockState || (ExceptionBlockState = {}));
    // NOTE: changes to this enum should be reflected in the __generator helper.
    var Instruction;
    (function (Instruction) {
        Instruction[Instruction["Next"] = 0] = "Next";
        Instruction[Instruction["Throw"] = 1] = "Throw";
        Instruction[Instruction["Return"] = 2] = "Return";
        Instruction[Instruction["Break"] = 3] = "Break";
        Instruction[Instruction["Yield"] = 4] = "Yield";
        Instruction[Instruction["YieldStar"] = 5] = "YieldStar";
        Instruction[Instruction["Catch"] = 6] = "Catch";
        Instruction[Instruction["Endfinally"] = 7] = "Endfinally";
    })(Instruction || (Instruction = {}));
    function getInstructionName(instruction) {
        switch (instruction) {
            case 2 /* Return */: return "return";
            case 3 /* Break */: return "break";
            case 4 /* Yield */: return "yield";
            case 5 /* YieldStar */: return "yield*";
            case 7 /* Endfinally */: return "endfinally";
        }
    }
    function transformGenerators(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistFunctionDeclaration = context.hoistFunctionDeclaration, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var renamedCatchVariables;
        var renamedCatchVariableDeclarations;
        var inGeneratorFunctionBody;
        var inStatementContainingYield;
        // The following three arrays store information about generated code blocks.
        // All three arrays are correlated by their index. This approach is used over allocating
        // objects to store the same information to avoid GC overhead.
        //
        var blocks; // Information about the code block
        var blockOffsets; // The operation offset at which a code block begins or ends
        var blockActions; // Whether the code block is opened or closed
        var blockStack; // A stack of currently open code blocks
        // Labels are used to mark locations in the code that can be the target of a Break (jump)
        // operation. These are translated into case clauses in a switch statement.
        // The following two arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var labelOffsets; // The operation offset at which the label is defined.
        var labelExpressions; // The NumericLiteral nodes bound to each label.
        var nextLabelId = 1; // The next label id to use.
        // Operations store information about generated code for the function body. This
        // Includes things like statements, assignments, breaks (jumps), and yields.
        // The following three arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var operations; // The operation to perform.
        var operationArguments; // The arguments to the operation.
        var operationLocations; // The source map location for the operation.
        var state; // The name of the state object used by the generator at runtime.
        // The following variables store information used by the `build` function:
        //
        var blockIndex = 0; // The index of the current block.
        var labelNumber = 0; // The current label number.
        var labelNumbers;
        var lastOperationWasAbrupt; // Indicates whether the last operation was abrupt (break/continue).
        var lastOperationWasCompletion; // Indicates whether the last operation was a completion (return/throw).
        var clauses; // The case clauses generated for labels.
        var statements; // The statements for the current label.
        var exceptionBlockStack; // A stack of containing exception blocks.
        var currentExceptionBlock; // The current exception block.
        var withBlockStack; // A stack containing `with` blocks.
        return transformSourceFile;
        function transformSourceFile(node) {
            if (node.isDeclarationFile || (node.transformFlags & 512 /* ContainsGenerator */) === 0) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        /**
         * Visits a node.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            var transformFlags = node.transformFlags;
            if (inStatementContainingYield) {
                return visitJavaScriptInStatementContainingYield(node);
            }
            else if (inGeneratorFunctionBody) {
                return visitJavaScriptInGeneratorFunctionBody(node);
            }
            else if (transformFlags & 256 /* Generator */) {
                return visitGenerator(node);
            }
            else if (transformFlags & 512 /* ContainsGenerator */) {
                return ts.visitEachChild(node, visitor, context);
            }
            else {
                return node;
            }
        }
        /**
         * Visits a node that is contained within a statement that contains yield.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInStatementContainingYield(node) {
            switch (node.kind) {
                case 212 /* DoStatement */:
                    return visitDoStatement(node);
                case 213 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 221 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 222 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                default:
                    return visitJavaScriptInGeneratorFunctionBody(node);
            }
        }
        /**
         * Visits a node that is contained within a generator function.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInGeneratorFunctionBody(node) {
            switch (node.kind) {
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 186 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 208 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 214 /* ForStatement */:
                    return visitForStatement(node);
                case 215 /* ForInStatement */:
                    return visitForInStatement(node);
                case 218 /* BreakStatement */:
                    return visitBreakStatement(node);
                case 217 /* ContinueStatement */:
                    return visitContinueStatement(node);
                case 219 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    if (node.transformFlags & 16777216 /* ContainsYield */) {
                        return visitJavaScriptContainingYield(node);
                    }
                    else if (node.transformFlags & (512 /* ContainsGenerator */ | 33554432 /* ContainsHoistedDeclarationOrCompletion */)) {
                        return ts.visitEachChild(node, visitor, context);
                    }
                    else {
                        return node;
                    }
            }
        }
        /**
         * Visits a node that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptContainingYield(node) {
            switch (node.kind) {
                case 194 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                case 195 /* ConditionalExpression */:
                    return visitConditionalExpression(node);
                case 197 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 177 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 178 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 180 /* ElementAccessExpression */:
                    return visitElementAccessExpression(node);
                case 181 /* CallExpression */:
                    return visitCallExpression(node);
                case 182 /* NewExpression */:
                    return visitNewExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        /**
         * Visits a generator function.
         *
         * @param node The node to visit.
         */
        function visitGenerator(node) {
            switch (node.kind) {
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 186 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                default:
                    ts.Debug.failBadSyntaxKind(node);
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        /**
         * Visits a function declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The function declaration is a generator function.
         * - The function declaration is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, node.modifiers, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            if (inGeneratorFunctionBody) {
                // Function declarations in a generator function body are hoisted
                // to the top of the lexical scope and elided from the current statement.
                hoistFunctionDeclaration(node);
                return undefined;
            }
            else {
                return node;
            }
        }
        /**
         * Visits a function expression.
         *
         * This will be called when one of the following conditions are met:
         * - The function expression is a generator function.
         * - The function expression is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            return node;
        }
        /**
         * Visits a get or set accessor declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The accessor is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitAccessorDeclaration(node) {
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            inGeneratorFunctionBody = false;
            inStatementContainingYield = false;
            node = ts.visitEachChild(node, visitor, context);
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            return node;
        }
        /**
         * Transforms the body of a generator function declaration.
         *
         * @param node The function body to transform.
         */
        function transformGeneratorFunctionBody(body) {
            // Save existing generator state
            var statements = [];
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            var savedBlocks = blocks;
            var savedBlockOffsets = blockOffsets;
            var savedBlockActions = blockActions;
            var savedBlockStack = blockStack;
            var savedLabelOffsets = labelOffsets;
            var savedLabelExpressions = labelExpressions;
            var savedNextLabelId = nextLabelId;
            var savedOperations = operations;
            var savedOperationArguments = operationArguments;
            var savedOperationLocations = operationLocations;
            var savedState = state;
            // Initialize generator state
            inGeneratorFunctionBody = true;
            inStatementContainingYield = false;
            blocks = undefined;
            blockOffsets = undefined;
            blockActions = undefined;
            blockStack = undefined;
            labelOffsets = undefined;
            labelExpressions = undefined;
            nextLabelId = 1;
            operations = undefined;
            operationArguments = undefined;
            operationLocations = undefined;
            state = ts.createTempVariable(/*recordTempVariable*/ undefined);
            // Build the generator
            resumeLexicalEnvironment();
            var statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            transformAndEmitStatements(body.statements, statementOffset);
            var buildResult = build();
            ts.addRange(statements, endLexicalEnvironment());
            statements.push(ts.createReturn(buildResult));
            // Restore previous generator state
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            blocks = savedBlocks;
            blockOffsets = savedBlockOffsets;
            blockActions = savedBlockActions;
            blockStack = savedBlockStack;
            labelOffsets = savedLabelOffsets;
            labelExpressions = savedLabelExpressions;
            nextLabelId = savedNextLabelId;
            operations = savedOperations;
            operationArguments = savedOperationArguments;
            operationLocations = savedOperationLocations;
            state = savedState;
            return ts.setTextRange(ts.createBlock(statements, body.multiLine), body);
        }
        /**
         * Visits a variable statement.
         *
         * This will be called when one of the following conditions are met:
         * - The variable statement is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (node.transformFlags & 16777216 /* ContainsYield */) {
                transformAndEmitVariableDeclarationList(node.declarationList);
                return undefined;
            }
            else {
                // Do not hoist custom prologues.
                if (ts.getEmitFlags(node) & 1048576 /* CustomPrologue */) {
                    return node;
                }
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    return undefined;
                }
                return ts.setSourceMapRange(ts.createStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
        }
        /**
         * Visits a binary expression.
         *
         * This will be called when one of the following conditions are met:
         * - The node contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitBinaryExpression(node) {
            switch (ts.getExpressionAssociativity(node)) {
                case 0 /* Left */:
                    return visitLeftAssociativeBinaryExpression(node);
                case 1 /* Right */:
                    return visitRightAssociativeBinaryExpression(node);
                default:
                    ts.Debug.fail("Unknown associativity.");
            }
        }
        function isCompoundAssignment(kind) {
            return kind >= 59 /* FirstCompoundAssignment */
                && kind <= 70 /* LastCompoundAssignment */;
        }
        function getOperatorForCompoundAssignment(kind) {
            switch (kind) {
                case 59 /* PlusEqualsToken */: return 37 /* PlusToken */;
                case 60 /* MinusEqualsToken */: return 38 /* MinusToken */;
                case 61 /* AsteriskEqualsToken */: return 39 /* AsteriskToken */;
                case 62 /* AsteriskAsteriskEqualsToken */: return 40 /* AsteriskAsteriskToken */;
                case 63 /* SlashEqualsToken */: return 41 /* SlashToken */;
                case 64 /* PercentEqualsToken */: return 42 /* PercentToken */;
                case 65 /* LessThanLessThanEqualsToken */: return 45 /* LessThanLessThanToken */;
                case 66 /* GreaterThanGreaterThanEqualsToken */: return 46 /* GreaterThanGreaterThanToken */;
                case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: return 47 /* GreaterThanGreaterThanGreaterThanToken */;
                case 68 /* AmpersandEqualsToken */: return 48 /* AmpersandToken */;
                case 69 /* BarEqualsToken */: return 49 /* BarToken */;
                case 70 /* CaretEqualsToken */: return 50 /* CaretToken */;
            }
        }
        /**
         * Visits a right-associative binary expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitRightAssociativeBinaryExpression(node) {
            var left = node.left, right = node.right;
            if (containsYield(right)) {
                var target = void 0;
                switch (left.kind) {
                    case 179 /* PropertyAccessExpression */:
                        // [source]
                        //      a.b = yield;
                        //
                        // [intermediate]
                        //  .local _a
                        //      _a = a;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a.b = %sent%;
                        target = ts.updatePropertyAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), left.name);
                        break;
                    case 180 /* ElementAccessExpression */:
                        // [source]
                        //      a[b] = yield;
                        //
                        // [intermediate]
                        //  .local _a, _b
                        //      _a = a;
                        //      _b = b;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a[_b] = %sent%;
                        target = ts.updateElementAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), cacheExpression(ts.visitNode(left.argumentExpression, visitor, ts.isExpression)));
                        break;
                    default:
                        target = ts.visitNode(left, visitor, ts.isExpression);
                        break;
                }
                var operator = node.operatorToken.kind;
                if (isCompoundAssignment(operator)) {
                    return ts.setTextRange(ts.createAssignment(target, ts.setTextRange(ts.createBinary(cacheExpression(target), getOperatorForCompoundAssignment(operator), ts.visitNode(right, visitor, ts.isExpression)), node)), node);
                }
                else {
                    return ts.updateBinary(node, target, ts.visitNode(right, visitor, ts.isExpression));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLeftAssociativeBinaryExpression(node) {
            if (containsYield(node.right)) {
                if (ts.isLogicalOperator(node.operatorToken.kind)) {
                    return visitLogicalBinaryExpression(node);
                }
                else if (node.operatorToken.kind === 26 /* CommaToken */) {
                    return visitCommaExpression(node);
                }
                // [source]
                //      a() + (yield) + c()
                //
                // [intermediate]
                //  .local _a
                //      _a = a();
                //  .yield resumeLabel
                //      _a + %sent% + c()
                var clone_4 = ts.getMutableClone(node);
                clone_4.left = cacheExpression(ts.visitNode(node.left, visitor, ts.isExpression));
                clone_4.right = ts.visitNode(node.right, visitor, ts.isExpression);
                return clone_4;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a logical binary expression containing `yield`.
         *
         * @param node A node to visit.
         */
        function visitLogicalBinaryExpression(node) {
            // Logical binary expressions (`&&` and `||`) are shortcutting expressions and need
            // to be transformed as such:
            //
            // [source]
            //      x = a() && yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brfalse resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            //
            // [source]
            //      x = a() || yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brtrue resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            var resultLabel = defineLabel();
            var resultLocal = declareLocal();
            emitAssignment(resultLocal, ts.visitNode(node.left, visitor, ts.isExpression), /*location*/ node.left);
            if (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */) {
                // Logical `&&` shortcuts when the left-hand operand is falsey.
                emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left);
            }
            else {
                // Logical `||` shortcuts when the left-hand operand is truthy.
                emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left);
            }
            emitAssignment(resultLocal, ts.visitNode(node.right, visitor, ts.isExpression), /*location*/ node.right);
            markLabel(resultLabel);
            return resultLocal;
        }
        /**
         * Visits a comma expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitCommaExpression(node) {
            // [source]
            //      x = a(), yield, b();
            //
            // [intermediate]
            //      a();
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      x = %sent%, b();
            var pendingExpressions = [];
            visit(node.left);
            visit(node.right);
            return ts.inlineExpressions(pendingExpressions);
            function visit(node) {
                if (ts.isBinaryExpression(node) && node.operatorToken.kind === 26 /* CommaToken */) {
                    visit(node.left);
                    visit(node.right);
                }
                else {
                    if (containsYield(node) && pendingExpressions.length > 0) {
                        emitWorker(1 /* Statement */, [ts.createStatement(ts.inlineExpressions(pendingExpressions))]);
                        pendingExpressions = [];
                    }
                    pendingExpressions.push(ts.visitNode(node, visitor, ts.isExpression));
                }
            }
        }
        /**
         * Visits a conditional expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitConditionalExpression(node) {
            // [source]
            //      x = a() ? yield : b();
            //
            // [intermediate]
            //  .local _a
            //  .brfalse whenFalseLabel, (a())
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .br resultLabel
            //  .mark whenFalseLabel
            //      _a = b();
            //  .mark resultLabel
            //      x = _a;
            // We only need to perform a specific transformation if a `yield` expression exists
            // in either the `whenTrue` or `whenFalse` branches.
            // A `yield` in the condition will be handled by the normal visitor.
            if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) {
                var whenFalseLabel = defineLabel();
                var resultLabel = defineLabel();
                var resultLocal = declareLocal();
                emitBreakWhenFalse(whenFalseLabel, ts.visitNode(node.condition, visitor, ts.isExpression), /*location*/ node.condition);
                emitAssignment(resultLocal, ts.visitNode(node.whenTrue, visitor, ts.isExpression), /*location*/ node.whenTrue);
                emitBreak(resultLabel);
                markLabel(whenFalseLabel);
                emitAssignment(resultLocal, ts.visitNode(node.whenFalse, visitor, ts.isExpression), /*location*/ node.whenFalse);
                markLabel(resultLabel);
                return resultLocal;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a `yield` expression.
         *
         * @param node The node to visit.
         */
        function visitYieldExpression(node) {
            // [source]
            //      x = yield a();
            //
            // [intermediate]
            //  .yield resumeLabel, (a())
            //  .mark resumeLabel
            //      x = %sent%;
            var resumeLabel = defineLabel();
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            if (node.asteriskToken) {
                var iterator = (ts.getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0
                    ? ts.createValuesHelper(context, expression, /*location*/ node)
                    : expression;
                emitYieldStar(iterator, /*location*/ node);
            }
            else {
                emitYield(expression, /*location*/ node);
            }
            markLabel(resumeLabel);
            return createGeneratorResume(/*location*/ node);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitArrayLiteralExpression(node) {
            return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine);
        }
        /**
         * Visits an array of expressions containing one or more YieldExpression nodes
         * and returns an expression for the resulting value.
         *
         * @param elements The elements to visit.
         * @param multiLine Whether array literals created should be emitted on multiple lines.
         */
        function visitElements(elements, leadingElement, location, multiLine) {
            // [source]
            //      ar = [1, yield, 2];
            //
            // [intermediate]
            //  .local _a
            //      _a = [1];
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      ar = _a.concat([%sent%, 2]);
            var numInitialElements = countInitialNodesWithoutYield(elements);
            var temp;
            if (numInitialElements > 0) {
                temp = declareLocal();
                var initialElements = ts.visitNodes(elements, visitor, ts.isExpression, 0, numInitialElements);
                emitAssignment(temp, ts.createArrayLiteral(leadingElement
                    ? [leadingElement].concat(initialElements) : initialElements));
                leadingElement = undefined;
            }
            var expressions = ts.reduceLeft(elements, reduceElement, [], numInitialElements);
            return temp
                ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                : ts.setTextRange(ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine), location);
            function reduceElement(expressions, element) {
                if (containsYield(element) && expressions.length > 0) {
                    var hasAssignedTemp = temp !== undefined;
                    if (!temp) {
                        temp = declareLocal();
                    }
                    emitAssignment(temp, hasAssignedTemp
                        ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                        : ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine));
                    leadingElement = undefined;
                    expressions = [];
                }
                expressions.push(ts.visitNode(element, visitor, ts.isExpression));
                return expressions;
            }
        }
        function visitObjectLiteralExpression(node) {
            // [source]
            //      o = {
            //          a: 1,
            //          b: yield,
            //          c: 2
            //      };
            //
            // [intermediate]
            //  .local _a
            //      _a = {
            //          a: 1
            //      };
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      o = (_a.b = %sent%,
            //          _a.c = 2,
            //          _a);
            var properties = node.properties;
            var multiLine = node.multiLine;
            var numInitialProperties = countInitialNodesWithoutYield(properties);
            var temp = declareLocal();
            emitAssignment(temp, ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), multiLine));
            var expressions = ts.reduceLeft(properties, reduceProperty, [], numInitialProperties);
            expressions.push(multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
            return ts.inlineExpressions(expressions);
            function reduceProperty(expressions, property) {
                if (containsYield(property) && expressions.length > 0) {
                    emitStatement(ts.createStatement(ts.inlineExpressions(expressions)));
                    expressions = [];
                }
                var expression = ts.createExpressionForObjectLiteralElementLike(node, property, temp);
                var visited = ts.visitNode(expression, visitor, ts.isExpression);
                if (visited) {
                    if (multiLine) {
                        visited.startsOnNewLine = true;
                    }
                    expressions.push(visited);
                }
                return expressions;
            }
        }
        /**
         * Visits an ElementAccessExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitElementAccessExpression(node) {
            if (containsYield(node.argumentExpression)) {
                // [source]
                //      a = x[yield];
                //
                // [intermediate]
                //  .local _a
                //      _a = x;
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      a = _a[%sent%]
                var clone_5 = ts.getMutableClone(node);
                clone_5.expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
                clone_5.argumentExpression = ts.visitNode(node.argumentExpression, visitor, ts.isExpression);
                return clone_5;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCallExpression(node) {
            if (!ts.isImportCall(node) && ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a).b;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      _b.apply(_a, _c.concat([%sent%, 2]));
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isLeftHandSideExpression)), thisArg, visitElements(node.arguments), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitNewExpression(node) {
            if (ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      new a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a.b).bind;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      new (_b.apply(_a, _c.concat([%sent%, 2])));
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.setTextRange(ts.createNew(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isExpression)), thisArg, visitElements(node.arguments, 
                /*leadingElement*/ ts.createVoidZero())), 
                /*typeArguments*/ undefined, []), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitStatements(statements, start) {
            if (start === void 0) { start = 0; }
            var numStatements = statements.length;
            for (var i = start; i < numStatements; i++) {
                transformAndEmitStatement(statements[i]);
            }
        }
        function transformAndEmitEmbeddedStatement(node) {
            if (ts.isBlock(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                transformAndEmitStatement(node);
            }
        }
        function transformAndEmitStatement(node) {
            var savedInStatementContainingYield = inStatementContainingYield;
            if (!inStatementContainingYield) {
                inStatementContainingYield = containsYield(node);
            }
            transformAndEmitStatementWorker(node);
            inStatementContainingYield = savedInStatementContainingYield;
        }
        function transformAndEmitStatementWorker(node) {
            switch (node.kind) {
                case 207 /* Block */:
                    return transformAndEmitBlock(node);
                case 210 /* ExpressionStatement */:
                    return transformAndEmitExpressionStatement(node);
                case 211 /* IfStatement */:
                    return transformAndEmitIfStatement(node);
                case 212 /* DoStatement */:
                    return transformAndEmitDoStatement(node);
                case 213 /* WhileStatement */:
                    return transformAndEmitWhileStatement(node);
                case 214 /* ForStatement */:
                    return transformAndEmitForStatement(node);
                case 215 /* ForInStatement */:
                    return transformAndEmitForInStatement(node);
                case 217 /* ContinueStatement */:
                    return transformAndEmitContinueStatement(node);
                case 218 /* BreakStatement */:
                    return transformAndEmitBreakStatement(node);
                case 219 /* ReturnStatement */:
                    return transformAndEmitReturnStatement(node);
                case 220 /* WithStatement */:
                    return transformAndEmitWithStatement(node);
                case 221 /* SwitchStatement */:
                    return transformAndEmitSwitchStatement(node);
                case 222 /* LabeledStatement */:
                    return transformAndEmitLabeledStatement(node);
                case 223 /* ThrowStatement */:
                    return transformAndEmitThrowStatement(node);
                case 224 /* TryStatement */:
                    return transformAndEmitTryStatement(node);
                default:
                    return emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitBlock(node) {
            if (containsYield(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitExpressionStatement(node) {
            emitStatement(ts.visitNode(node, visitor, ts.isStatement));
        }
        function transformAndEmitVariableDeclarationList(node) {
            for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                var name = ts.getSynthesizedClone(variable.name);
                ts.setCommentRange(name, variable.name);
                hoistVariableDeclaration(name);
            }
            var variables = ts.getInitializedVariables(node);
            var numVariables = variables.length;
            var variablesWritten = 0;
            var pendingExpressions = [];
            while (variablesWritten < numVariables) {
                for (var i = variablesWritten; i < numVariables; i++) {
                    var variable = variables[i];
                    if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
                        break;
                    }
                    pendingExpressions.push(transformInitializedVariable(variable));
                }
                if (pendingExpressions.length) {
                    emitStatement(ts.createStatement(ts.inlineExpressions(pendingExpressions)));
                    variablesWritten += pendingExpressions.length;
                    pendingExpressions = [];
                }
            }
            return undefined;
        }
        function transformInitializedVariable(node) {
            return ts.setSourceMapRange(ts.createAssignment(ts.setSourceMapRange(ts.getSynthesizedClone(node.name), node.name), ts.visitNode(node.initializer, visitor, ts.isExpression)), node);
        }
        function transformAndEmitIfStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      if (x)
                //          /*thenStatement*/
                //      else
                //          /*elseStatement*/
                //
                // [intermediate]
                //  .brfalse elseLabel, (x)
                //      /*thenStatement*/
                //  .br endLabel
                //  .mark elseLabel
                //      /*elseStatement*/
                //  .mark endLabel
                if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
                    var endLabel = defineLabel();
                    var elseLabel = node.elseStatement ? defineLabel() : undefined;
                    emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node.expression);
                    transformAndEmitEmbeddedStatement(node.thenStatement);
                    if (node.elseStatement) {
                        emitBreak(endLabel);
                        markLabel(elseLabel);
                        transformAndEmitEmbeddedStatement(node.elseStatement);
                    }
                    markLabel(endLabel);
                }
                else {
                    emitStatement(ts.visitNode(node, visitor, ts.isStatement));
                }
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitDoStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      do {
                //          /*body*/
                //      }
                //      while (i < 10);
                //
                // [intermediate]
                //  .loop conditionLabel, endLabel
                //  .mark loopLabel
                //      /*body*/
                //  .mark conditionLabel
                //  .brtrue loopLabel, (i < 10)
                //  .endloop
                //  .mark endLabel
                var conditionLabel = defineLabel();
                var loopLabel = defineLabel();
                beginLoopBlock(/*continueLabel*/ conditionLabel);
                markLabel(loopLabel);
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(conditionLabel);
                emitBreakWhenTrue(loopLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitDoStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitWhileStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      while (i < 10) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .loop loopLabel, endLabel
                //  .mark loopLabel
                //  .brfalse endLabel, (i < 10)
                //      /*body*/
                //  .br loopLabel
                //  .endloop
                //  .mark endLabel
                var loopLabel = defineLabel();
                var endLabel = beginLoopBlock(loopLabel);
                markLabel(loopLabel);
                emitBreakWhenFalse(endLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                transformAndEmitEmbeddedStatement(node.statement);
                emitBreak(loopLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitWhileStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitForStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      for (var i = 0; i < 10; i++) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local i
                //      i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (i < 10)
                //      /*body*/
                //  .mark incrementLabel
                //      i++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                if (node.initializer) {
                    var initializer = node.initializer;
                    if (ts.isVariableDeclarationList(initializer)) {
                        transformAndEmitVariableDeclarationList(initializer);
                    }
                    else {
                        emitStatement(ts.setTextRange(ts.createStatement(ts.visitNode(initializer, visitor, ts.isExpression)), initializer));
                    }
                }
                markLabel(conditionLabel);
                if (node.condition) {
                    emitBreakWhenFalse(endLabel, ts.visitNode(node.condition, visitor, ts.isExpression));
                }
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                if (node.incrementor) {
                    emitStatement(ts.setTextRange(ts.createStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), node.incrementor));
                }
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (initializer && ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(initializer);
                node = ts.updateFor(node, variables.length > 0
                    ? ts.inlineExpressions(ts.map(variables, transformInitializedVariable))
                    : undefined, ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitForInStatement(node) {
            // TODO(rbuckton): Source map locations
            if (containsYield(node)) {
                // [source]
                //      for (var p in o) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local _a, _b, _i
                //      _a = [];
                //      for (_b in o) _a.push(_b);
                //      _i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (_i < _a.length)
                //      p = _a[_i];
                //      /*body*/
                //  .mark incrementLabel
                //      _b++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var keysArray = declareLocal(); // _a
                var key = declareLocal(); // _b
                var keysIndex = ts.createLoopVariable(); // _i
                var initializer = node.initializer;
                hoistVariableDeclaration(keysIndex);
                emitAssignment(keysArray, ts.createArrayLiteral());
                emitStatement(ts.createForIn(key, ts.visitNode(node.expression, visitor, ts.isExpression), ts.createStatement(ts.createCall(ts.createPropertyAccess(keysArray, "push"), 
                /*typeArguments*/ undefined, [key]))));
                emitAssignment(keysIndex, ts.createLiteral(0));
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                markLabel(conditionLabel);
                emitBreakWhenFalse(endLabel, ts.createLessThan(keysIndex, ts.createPropertyAccess(keysArray, "length")));
                var variable = void 0;
                if (ts.isVariableDeclarationList(initializer)) {
                    for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                        var variable_1 = _a[_i];
                        hoistVariableDeclaration(variable_1.name);
                    }
                    variable = ts.getSynthesizedClone(initializer.declarations[0].name);
                }
                else {
                    variable = ts.visitNode(initializer, visitor, ts.isExpression);
                    ts.Debug.assert(ts.isLeftHandSideExpression(variable));
                }
                emitAssignment(variable, ts.createElementAccess(keysArray, keysIndex));
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                emitStatement(ts.createStatement(ts.createPostfixIncrement(keysIndex)));
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForInStatement(node) {
            // [source]
            //      for (var x in a) {
            //          /*body*/
            //      }
            //
            // [intermediate]
            //  .local x
            //  .loop
            //      for (x in a) {
            //          /*body*/
            //      }
            //  .endloop
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                node = ts.updateForIn(node, initializer.declarations[0].name, ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitContinueStatement(node) {
            var label = findContinueTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid continue without a containing loop. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitContinueStatement(node) {
            if (inStatementContainingYield) {
                var label = findContinueTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitBreakStatement(node) {
            var label = findBreakTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitBreakStatement(node) {
            if (inStatementContainingYield) {
                var label = findBreakTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitReturnStatement(node) {
            emitReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function visitReturnStatement(node) {
            return createInlineReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitWithStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      with (x) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .with (x)
                //      /*body*/
                //  .endwith
                beginWithBlock(cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression)));
                transformAndEmitEmbeddedStatement(node.statement);
                endWithBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitSwitchStatement(node) {
            if (containsYield(node.caseBlock)) {
                // [source]
                //      switch (x) {
                //          case a:
                //              /*caseStatements*/
                //          case b:
                //              /*caseStatements*/
                //          default:
                //              /*defaultStatements*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .switch endLabel
                //      _a = x;
                //      switch (_a) {
                //          case a:
                //  .br clauseLabels[0]
                //      }
                //      switch (_a) {
                //          case b:
                //  .br clauseLabels[1]
                //      }
                //  .br clauseLabels[2]
                //  .mark clauseLabels[0]
                //      /*caseStatements*/
                //  .mark clauseLabels[1]
                //      /*caseStatements*/
                //  .mark clauseLabels[2]
                //      /*caseStatements*/
                //  .endswitch
                //  .mark endLabel
                var caseBlock = node.caseBlock;
                var numClauses = caseBlock.clauses.length;
                var endLabel = beginSwitchBlock();
                var expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression));
                // Create labels for each clause and find the index of the first default clause.
                var clauseLabels = [];
                var defaultClauseIndex = -1;
                for (var i = 0; i < numClauses; i++) {
                    var clause = caseBlock.clauses[i];
                    clauseLabels.push(defineLabel());
                    if (clause.kind === 258 /* DefaultClause */ && defaultClauseIndex === -1) {
                        defaultClauseIndex = i;
                    }
                }
                // Emit switch statements for each run of case clauses either from the first case
                // clause or the next case clause with a `yield` in its expression, up to the next
                // case clause with a `yield` in its expression.
                var clausesWritten = 0;
                var pendingClauses = [];
                while (clausesWritten < numClauses) {
                    var defaultClausesSkipped = 0;
                    for (var i = clausesWritten; i < numClauses; i++) {
                        var clause = caseBlock.clauses[i];
                        if (clause.kind === 257 /* CaseClause */) {
                            var caseClause = clause;
                            if (containsYield(caseClause.expression) && pendingClauses.length > 0) {
                                break;
                            }
                            pendingClauses.push(ts.createCaseClause(ts.visitNode(caseClause.expression, visitor, ts.isExpression), [
                                createInlineBreak(clauseLabels[i], /*location*/ caseClause.expression)
                            ]));
                        }
                        else {
                            defaultClausesSkipped++;
                        }
                    }
                    if (pendingClauses.length) {
                        emitStatement(ts.createSwitch(expression, ts.createCaseBlock(pendingClauses)));
                        clausesWritten += pendingClauses.length;
                        pendingClauses = [];
                    }
                    if (defaultClausesSkipped > 0) {
                        clausesWritten += defaultClausesSkipped;
                        defaultClausesSkipped = 0;
                    }
                }
                if (defaultClauseIndex >= 0) {
                    emitBreak(clauseLabels[defaultClauseIndex]);
                }
                else {
                    emitBreak(endLabel);
                }
                for (var i = 0; i < numClauses; i++) {
                    markLabel(clauseLabels[i]);
                    transformAndEmitStatements(caseBlock.clauses[i].statements);
                }
                endSwitchBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitSwitchStatement(node) {
            if (inStatementContainingYield) {
                beginScriptSwitchBlock();
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endSwitchBlock();
            }
            return node;
        }
        function transformAndEmitLabeledStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      x: {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .labeled "x", endLabel
                //      /*body*/
                //  .endlabeled
                //  .mark endLabel
                beginLabeledBlock(ts.idText(node.label));
                transformAndEmitEmbeddedStatement(node.statement);
                endLabeledBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitLabeledStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLabeledBlock(ts.idText(node.label));
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endLabeledBlock();
            }
            return node;
        }
        function transformAndEmitThrowStatement(node) {
            emitThrow(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitTryStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      try {
                //          /*tryBlock*/
                //      }
                //      catch (e) {
                //          /*catchBlock*/
                //      }
                //      finally {
                //          /*finallyBlock*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .try tryLabel, catchLabel, finallyLabel, endLabel
                //  .mark tryLabel
                //  .nop
                //      /*tryBlock*/
                //  .br endLabel
                //  .catch
                //  .mark catchLabel
                //      _a = %error%;
                //      /*catchBlock*/
                //  .br endLabel
                //  .finally
                //  .mark finallyLabel
                //      /*finallyBlock*/
                //  .endfinally
                //  .endtry
                //  .mark endLabel
                beginExceptionBlock();
                transformAndEmitEmbeddedStatement(node.tryBlock);
                if (node.catchClause) {
                    beginCatchBlock(node.catchClause.variableDeclaration);
                    transformAndEmitEmbeddedStatement(node.catchClause.block);
                }
                if (node.finallyBlock) {
                    beginFinallyBlock();
                    transformAndEmitEmbeddedStatement(node.finallyBlock);
                }
                endExceptionBlock();
            }
            else {
                emitStatement(ts.visitEachChild(node, visitor, context));
            }
        }
        function containsYield(node) {
            return node && (node.transformFlags & 16777216 /* ContainsYield */) !== 0;
        }
        function countInitialNodesWithoutYield(nodes) {
            var numNodes = nodes.length;
            for (var i = 0; i < numNodes; i++) {
                if (containsYield(nodes[i])) {
                    return i;
                }
            }
            return -1;
        }
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            if (ts.isIdentifier(node)) {
                return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            if (!ts.isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(ts.idText(node))) {
                var original = ts.getOriginalNode(node);
                if (ts.isIdentifier(original) && original.parent) {
                    var declaration = resolver.getReferencedValueDeclaration(original);
                    if (declaration) {
                        var name = renamedCatchVariableDeclarations[ts.getOriginalNodeId(declaration)];
                        if (name) {
                            var clone_6 = ts.getMutableClone(name);
                            ts.setSourceMapRange(clone_6, node);
                            ts.setCommentRange(clone_6, node);
                            return clone_6;
                        }
                    }
                }
            }
            return node;
        }
        function cacheExpression(node) {
            var temp;
            if (ts.isGeneratedIdentifier(node) || ts.getEmitFlags(node) & 4096 /* HelperName */) {
                return node;
            }
            temp = ts.createTempVariable(hoistVariableDeclaration);
            emitAssignment(temp, node, /*location*/ node);
            return temp;
        }
        function declareLocal(name) {
            var temp = name
                ? ts.createUniqueName(name)
                : ts.createTempVariable(/*recordTempVariable*/ undefined);
            hoistVariableDeclaration(temp);
            return temp;
        }
        /**
         * Defines a label, uses as the target of a Break operation.
         */
        function defineLabel() {
            if (!labelOffsets) {
                labelOffsets = [];
            }
            var label = nextLabelId;
            nextLabelId++;
            labelOffsets[label] = -1;
            return label;
        }
        /**
         * Marks the current operation with the specified label.
         */
        function markLabel(label) {
            ts.Debug.assert(labelOffsets !== undefined, "No labels were defined.");
            labelOffsets[label] = operations ? operations.length : 0;
        }
        /**
         * Begins a block operation (With, Break/Continue, Try/Catch/Finally)
         *
         * @param block Information about the block.
         */
        function beginBlock(block) {
            if (!blocks) {
                blocks = [];
                blockActions = [];
                blockOffsets = [];
                blockStack = [];
            }
            var index = blockActions.length;
            blockActions[index] = 0 /* Open */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.push(block);
            return index;
        }
        /**
         * Ends the current block operation.
         */
        function endBlock() {
            var block = peekBlock();
            ts.Debug.assert(block !== undefined, "beginBlock was never called.");
            var index = blockActions.length;
            blockActions[index] = 1 /* Close */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.pop();
            return block;
        }
        /**
         * Gets the current open block.
         */
        function peekBlock() {
            return ts.lastOrUndefined(blockStack);
        }
        /**
         * Gets the kind of the current open block.
         */
        function peekBlockKind() {
            var block = peekBlock();
            return block && block.kind;
        }
        /**
         * Begins a code block for a generated `with` statement.
         *
         * @param expression An identifier representing expression for the `with` block.
         */
        function beginWithBlock(expression) {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 1 /* With */,
                expression: expression,
                startLabel: startLabel,
                endLabel: endLabel
            });
        }
        /**
         * Ends a code block for a generated `with` statement.
         */
        function endWithBlock() {
            ts.Debug.assert(peekBlockKind() === 1 /* With */);
            var block = endBlock();
            markLabel(block.endLabel);
        }
        /**
         * Begins a code block for a generated `try` statement.
         */
        function beginExceptionBlock() {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 0 /* Exception */,
                state: 0 /* Try */,
                startLabel: startLabel,
                endLabel: endLabel
            });
            emitNop();
            return endLabel;
        }
        /**
         * Enters the `catch` clause of a generated `try` statement.
         *
         * @param variable The catch variable.
         */
        function beginCatchBlock(variable) {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            // generated identifiers should already be unique within a file
            var name;
            if (ts.isGeneratedIdentifier(variable.name)) {
                name = variable.name;
                hoistVariableDeclaration(variable.name);
            }
            else {
                var text = ts.idText(variable.name);
                name = declareLocal(text);
                if (!renamedCatchVariables) {
                    renamedCatchVariables = ts.createMap();
                    renamedCatchVariableDeclarations = [];
                    context.enableSubstitution(71 /* Identifier */);
                }
                renamedCatchVariables.set(text, true);
                renamedCatchVariableDeclarations[ts.getOriginalNodeId(variable)] = name;
            }
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 1 /* Catch */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var catchLabel = defineLabel();
            markLabel(catchLabel);
            exception.state = 1 /* Catch */;
            exception.catchVariable = name;
            exception.catchLabel = catchLabel;
            emitAssignment(name, ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, []));
            emitNop();
        }
        /**
         * Enters the `finally` block of a generated `try` statement.
         */
        function beginFinallyBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 2 /* Finally */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var finallyLabel = defineLabel();
            markLabel(finallyLabel);
            exception.state = 2 /* Finally */;
            exception.finallyLabel = finallyLabel;
        }
        /**
         * Ends the code block for a generated `try` statement.
         */
        function endExceptionBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = endBlock();
            var state = exception.state;
            if (state < 2 /* Finally */) {
                emitBreak(exception.endLabel);
            }
            else {
                emitEndfinally();
            }
            markLabel(exception.endLabel);
            emitNop();
            exception.state = 3 /* Done */;
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * the source tree and not from generated code.
         *
         * @param labelText Names from containing labeled statements.
         */
        function beginScriptLoopBlock() {
            beginBlock({
                kind: 3 /* Loop */,
                isScript: true,
                breakLabel: -1,
                continueLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * generated code. Returns a label used to mark the operation to which to jump when a
         * `break` statement targets this block.
         *
         * @param continueLabel A Label used to mark the operation to which to jump when a
         *                      `continue` statement targets this block.
         */
        function beginLoopBlock(continueLabel) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 3 /* Loop */,
                isScript: false,
                breakLabel: breakLabel,
                continueLabel: continueLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` or `continue` statements that are defined in
         * generated code or in the source tree.
         */
        function endLoopBlock() {
            ts.Debug.assert(peekBlockKind() === 3 /* Loop */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        /**
         * Begins a code block that supports `break` statements that are defined in the source
         * tree and not from generated code.
         *
         */
        function beginScriptSwitchBlock() {
            beginBlock({
                kind: 2 /* Switch */,
                isScript: true,
                breakLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` statements that are defined in generated code.
         * Returns a label used to mark the operation to which to jump when a `break` statement
         * targets this block.
         */
        function beginSwitchBlock() {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 2 /* Switch */,
                isScript: false,
                breakLabel: breakLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` statements that are defined in generated code.
         */
        function endSwitchBlock() {
            ts.Debug.assert(peekBlockKind() === 2 /* Switch */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        function beginScriptLabeledBlock(labelText) {
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: true,
                labelText: labelText,
                breakLabel: -1
            });
        }
        function beginLabeledBlock(labelText) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: false,
                labelText: labelText,
                breakLabel: breakLabel
            });
        }
        function endLabeledBlock() {
            ts.Debug.assert(peekBlockKind() === 4 /* Labeled */);
            var block = endBlock();
            if (!block.isScript) {
                markLabel(block.breakLabel);
            }
        }
        /**
         * Indicates whether the provided block supports `break` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledBreak(block) {
            return block.kind === 2 /* Switch */
                || block.kind === 3 /* Loop */;
        }
        /**
         * Indicates whether the provided block supports `break` statements with labels.
         *
         * @param block A code block.
         */
        function supportsLabeledBreakOrContinue(block) {
            return block.kind === 4 /* Labeled */;
        }
        /**
         * Indicates whether the provided block supports `continue` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledContinue(block) {
            return block.kind === 3 /* Loop */;
        }
        function hasImmediateContainingLabeledBlock(labelText, start) {
            for (var j = start; j >= 0; j--) {
                var containingBlock = blockStack[j];
                if (supportsLabeledBreakOrContinue(containingBlock)) {
                    if (containingBlock.labelText === labelText) {
                        return true;
                    }
                }
                else {
                    break;
                }
            }
            return false;
        }
        /**
         * Finds the label that is the target for a `break` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findBreakTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
                            return block.breakLabel;
                        }
                        else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.breakLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledBreak(block)) {
                            return block.breakLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Finds the label that is the target for a `continue` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findContinueTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.continueLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block)) {
                            return block.continueLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Creates an expression that can be used to indicate the value for a label.
         *
         * @param label A label.
         */
        function createLabel(label) {
            if (label > 0) {
                if (labelExpressions === undefined) {
                    labelExpressions = [];
                }
                var expression = ts.createLiteral(-1);
                if (labelExpressions[label] === undefined) {
                    labelExpressions[label] = [expression];
                }
                else {
                    labelExpressions[label].push(expression);
                }
                return expression;
            }
            return ts.createOmittedExpression();
        }
        /**
         * Creates a numeric literal for the provided instruction.
         */
        function createInstruction(instruction) {
            var literal = ts.createLiteral(instruction);
            ts.addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction));
            return literal;
        }
        /**
         * Creates a statement that can be used indicate a Break operation to the provided label.
         *
         * @param label A label.
         * @param location An optional source map location for the statement.
         */
        function createInlineBreak(label, location) {
            ts.Debug.assertLessThan(0, label, "Invalid label");
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), location);
        }
        /**
         * Creates a statement that can be used indicate a Return operation.
         *
         * @param expression The expression for the return statement.
         * @param location An optional source map location for the statement.
         */
        function createInlineReturn(expression, location) {
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), location);
        }
        /**
         * Creates an expression that can be used to resume from a Yield operation.
         */
        function createGeneratorResume(location) {
            return ts.setTextRange(ts.createCall(ts.createPropertyAccess(state, "sent"), 
            /*typeArguments*/ undefined, []), location);
        }
        /**
         * Emits an empty instruction.
         */
        function emitNop() {
            emitWorker(0 /* Nop */);
        }
        /**
         * Emits a Statement.
         *
         * @param node A statement.
         */
        function emitStatement(node) {
            if (node) {
                emitWorker(1 /* Statement */, [node]);
            }
            else {
                emitNop();
            }
        }
        /**
         * Emits an Assignment operation.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param location An optional source map location for the assignment.
         */
        function emitAssignment(left, right, location) {
            emitWorker(2 /* Assign */, [left, right], location);
        }
        /**
         * Emits a Break operation to the specified label.
         *
         * @param label A label.
         * @param location An optional source map location for the assignment.
         */
        function emitBreak(label, location) {
            emitWorker(3 /* Break */, [label], location);
        }
        /**
         * Emits a Break operation to the specified label when a condition evaluates to a truthy
         * value at runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenTrue(label, condition, location) {
            emitWorker(4 /* BreakWhenTrue */, [label, condition], location);
        }
        /**
         * Emits a Break to the specified label when a condition evaluates to a falsey value at
         * runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenFalse(label, condition, location) {
            emitWorker(5 /* BreakWhenFalse */, [label, condition], location);
        }
        /**
         * Emits a YieldStar operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYieldStar(expression, location) {
            emitWorker(7 /* YieldStar */, [expression], location);
        }
        /**
         * Emits a Yield operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYield(expression, location) {
            emitWorker(6 /* Yield */, [expression], location);
        }
        /**
         * Emits a Return operation for the provided expression.
         *
         * @param expression An optional value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitReturn(expression, location) {
            emitWorker(8 /* Return */, [expression], location);
        }
        /**
         * Emits a Throw operation for the provided expression.
         *
         * @param expression A value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitThrow(expression, location) {
            emitWorker(9 /* Throw */, [expression], location);
        }
        /**
         * Emits an Endfinally operation. This is used to handle `finally` block semantics.
         */
        function emitEndfinally() {
            emitWorker(10 /* Endfinally */);
        }
        /**
         * Emits an operation.
         *
         * @param code The OpCode for the operation.
         * @param args The optional arguments for the operation.
         */
        function emitWorker(code, args, location) {
            if (operations === undefined) {
                operations = [];
                operationArguments = [];
                operationLocations = [];
            }
            if (labelOffsets === undefined) {
                // mark entry point
                markLabel(defineLabel());
            }
            var operationIndex = operations.length;
            operations[operationIndex] = code;
            operationArguments[operationIndex] = args;
            operationLocations[operationIndex] = location;
        }
        /**
         * Builds the generator function body.
         */
        function build() {
            blockIndex = 0;
            labelNumber = 0;
            labelNumbers = undefined;
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            clauses = undefined;
            statements = undefined;
            exceptionBlockStack = undefined;
            currentExceptionBlock = undefined;
            withBlockStack = undefined;
            var buildResult = buildStatements();
            return createGeneratorHelper(context, ts.setEmitFlags(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], 
            /*type*/ undefined, ts.createBlock(buildResult, 
            /*multiLine*/ buildResult.length > 0)), 524288 /* ReuseTempVariableScope */));
        }
        /**
         * Builds the statements for the generator function body.
         */
        function buildStatements() {
            if (operations) {
                for (var operationIndex = 0; operationIndex < operations.length; operationIndex++) {
                    writeOperation(operationIndex);
                }
                flushFinalLabel(operations.length);
            }
            else {
                flushFinalLabel(0);
            }
            if (clauses) {
                var labelExpression = ts.createPropertyAccess(state, "label");
                var switchStatement = ts.createSwitch(labelExpression, ts.createCaseBlock(clauses));
                switchStatement.startsOnNewLine = true;
                return [switchStatement];
            }
            if (statements) {
                return statements;
            }
            return [];
        }
        /**
         * Flush the current label and advance to a new label.
         */
        function flushLabel() {
            if (!statements) {
                return;
            }
            appendLabel(/*markLabelEnd*/ !lastOperationWasAbrupt);
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            labelNumber++;
        }
        /**
         * Flush the final label of the generator function body.
         */
        function flushFinalLabel(operationIndex) {
            if (isFinalLabelReachable(operationIndex)) {
                tryEnterLabel(operationIndex);
                withBlockStack = undefined;
                writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined);
            }
            if (statements && clauses) {
                appendLabel(/*markLabelEnd*/ false);
            }
            updateLabelExpressions();
        }
        /**
         * Tests whether the final label of the generator function body
         * is reachable by user code.
         */
        function isFinalLabelReachable(operationIndex) {
            // if the last operation was *not* a completion (return/throw) then
            // the final label is reachable.
            if (!lastOperationWasCompletion) {
                return true;
            }
            // if there are no labels defined or referenced, then the final label is
            // not reachable.
            if (!labelOffsets || !labelExpressions) {
                return false;
            }
            // if the label for this offset is referenced, then the final label
            // is reachable.
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Appends a case clause for the last label and sets the new label.
         *
         * @param markLabelEnd Indicates that the transition between labels was a fall-through
         *                     from a previous case clause and the change in labels should be
         *                     reflected on the `state` object.
         */
        function appendLabel(markLabelEnd) {
            if (!clauses) {
                clauses = [];
            }
            if (statements) {
                if (withBlockStack) {
                    // The previous label was nested inside one or more `with` blocks, so we
                    // surround the statements in generated `with` blocks to create the same environment.
                    for (var i = withBlockStack.length - 1; i >= 0; i--) {
                        var withBlock = withBlockStack[i];
                        statements = [ts.createWith(withBlock.expression, ts.createBlock(statements))];
                    }
                }
                if (currentExceptionBlock) {
                    // The previous label was nested inside of an exception block, so we must
                    // indicate entry into a protected region by pushing the label numbers
                    // for each block in the protected region.
                    var startLabel = currentExceptionBlock.startLabel, catchLabel = currentExceptionBlock.catchLabel, finallyLabel = currentExceptionBlock.finallyLabel, endLabel = currentExceptionBlock.endLabel;
                    statements.unshift(ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(state, "trys"), "push"), 
                    /*typeArguments*/ undefined, [
                        ts.createArrayLiteral([
                            createLabel(startLabel),
                            createLabel(catchLabel),
                            createLabel(finallyLabel),
                            createLabel(endLabel)
                        ])
                    ])));
                    currentExceptionBlock = undefined;
                }
                if (markLabelEnd) {
                    // The case clause for the last label falls through to this label, so we
                    // add an assignment statement to reflect the change in labels.
                    statements.push(ts.createStatement(ts.createAssignment(ts.createPropertyAccess(state, "label"), ts.createLiteral(labelNumber + 1))));
                }
            }
            clauses.push(ts.createCaseClause(ts.createLiteral(labelNumber), statements || []));
            statements = undefined;
        }
        /**
         * Tries to enter into a new label at the current operation index.
         */
        function tryEnterLabel(operationIndex) {
            if (!labelOffsets) {
                return;
            }
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex) {
                    flushLabel();
                    if (labelNumbers === undefined) {
                        labelNumbers = [];
                    }
                    if (labelNumbers[labelNumber] === undefined) {
                        labelNumbers[labelNumber] = [label];
                    }
                    else {
                        labelNumbers[labelNumber].push(label);
                    }
                }
            }
        }
        /**
         * Updates literal expressions for labels with actual label numbers.
         */
        function updateLabelExpressions() {
            if (labelExpressions !== undefined && labelNumbers !== undefined) {
                for (var labelNumber_1 = 0; labelNumber_1 < labelNumbers.length; labelNumber_1++) {
                    var labels = labelNumbers[labelNumber_1];
                    if (labels !== undefined) {
                        for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) {
                            var label = labels_1[_i];
                            var expressions = labelExpressions[label];
                            if (expressions !== undefined) {
                                for (var _a = 0, expressions_1 = expressions; _a < expressions_1.length; _a++) {
                                    var expression = expressions_1[_a];
                                    expression.text = String(labelNumber_1);
                                }
                            }
                        }
                    }
                }
            }
        }
        /**
         * Tries to enter or leave a code block.
         */
        function tryEnterOrLeaveBlock(operationIndex) {
            if (blocks) {
                for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
                    var block = blocks[blockIndex];
                    var blockAction = blockActions[blockIndex];
                    switch (block.kind) {
                        case 0 /* Exception */:
                            if (blockAction === 0 /* Open */) {
                                if (!exceptionBlockStack) {
                                    exceptionBlockStack = [];
                                }
                                if (!statements) {
                                    statements = [];
                                }
                                exceptionBlockStack.push(currentExceptionBlock);
                                currentExceptionBlock = block;
                            }
                            else if (blockAction === 1 /* Close */) {
                                currentExceptionBlock = exceptionBlockStack.pop();
                            }
                            break;
                        case 1 /* With */:
                            if (blockAction === 0 /* Open */) {
                                if (!withBlockStack) {
                                    withBlockStack = [];
                                }
                                withBlockStack.push(block);
                            }
                            else if (blockAction === 1 /* Close */) {
                                withBlockStack.pop();
                            }
                            break;
                    }
                }
            }
        }
        /**
         * Writes an operation as a statement to the current label's statement list.
         *
         * @param operation The OpCode of the operation
         */
        function writeOperation(operationIndex) {
            tryEnterLabel(operationIndex);
            tryEnterOrLeaveBlock(operationIndex);
            // early termination, nothing else to process in this label
            if (lastOperationWasAbrupt) {
                return;
            }
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            var opcode = operations[operationIndex];
            if (opcode === 0 /* Nop */) {
                return;
            }
            else if (opcode === 10 /* Endfinally */) {
                return writeEndfinally();
            }
            var args = operationArguments[operationIndex];
            if (opcode === 1 /* Statement */) {
                return writeStatement(args[0]);
            }
            var location = operationLocations[operationIndex];
            switch (opcode) {
                case 2 /* Assign */:
                    return writeAssign(args[0], args[1], location);
                case 3 /* Break */:
                    return writeBreak(args[0], location);
                case 4 /* BreakWhenTrue */:
                    return writeBreakWhenTrue(args[0], args[1], location);
                case 5 /* BreakWhenFalse */:
                    return writeBreakWhenFalse(args[0], args[1], location);
                case 6 /* Yield */:
                    return writeYield(args[0], location);
                case 7 /* YieldStar */:
                    return writeYieldStar(args[0], location);
                case 8 /* Return */:
                    return writeReturn(args[0], location);
                case 9 /* Throw */:
                    return writeThrow(args[0], location);
            }
        }
        /**
         * Writes a statement to the current label's statement list.
         *
         * @param statement A statement to write.
         */
        function writeStatement(statement) {
            if (statement) {
                if (!statements) {
                    statements = [statement];
                }
                else {
                    statements.push(statement);
                }
            }
        }
        /**
         * Writes an Assign operation to the current label's statement list.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param operationLocation The source map location for the operation.
         */
        function writeAssign(left, right, operationLocation) {
            writeStatement(ts.setTextRange(ts.createStatement(ts.createAssignment(left, right)), operationLocation));
        }
        /**
         * Writes a Throw operation to the current label's statement list.
         *
         * @param expression The value to throw.
         * @param operationLocation The source map location for the operation.
         */
        function writeThrow(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setTextRange(ts.createThrow(expression), operationLocation));
        }
        /**
         * Writes a Return operation to the current label's statement list.
         *
         * @param expression The value to return.
         * @param operationLocation The source map location for the operation.
         */
        function writeReturn(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a Break operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreak(label, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a BreakWhenTrue operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenTrue(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(condition, ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a BreakWhenFalse operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenFalse(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(ts.createLogicalNot(condition), ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a Yield operation to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYield(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(4 /* Yield */), expression]
                : [createInstruction(4 /* Yield */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a YieldStar instruction to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYieldStar(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(5 /* YieldStar */),
                expression
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes an Endfinally instruction to the current label's statement list.
         */
        function writeEndfinally() {
            lastOperationWasAbrupt = true;
            writeStatement(ts.createReturn(ts.createArrayLiteral([
                createInstruction(7 /* Endfinally */)
            ])));
        }
    }
    ts.transformGenerators = transformGenerators;
    function createGeneratorHelper(context, body) {
        context.requestEmitHelper(generatorHelper);
        return ts.createCall(ts.getHelperName("__generator"), 
        /*typeArguments*/ undefined, [ts.createThis(), body]);
    }
    // The __generator helper is used by down-level transformations to emulate the runtime
    // semantics of an ES2015 generator function. When called, this helper returns an
    // object that implements the Iterator protocol, in that it has `next`, `return`, and
    // `throw` methods that step through the generator when invoked.
    //
    // parameters:
    //  thisArg  The value to use as the `this` binding for the transformed generator body.
    //  body     A function that acts as the transformed generator body.
    //
    // variables:
    //  _       Persistent state for the generator that is shared between the helper and the
    //          generator body. The state object has the following members:
    //            sent() - A method that returns or throws the current completion value.
    //            label  - The next point at which to resume evaluation of the generator body.
    //            trys   - A stack of protected regions (try/catch/finally blocks).
    //            ops    - A stack of pending instructions when inside of a finally block.
    //  f       A value indicating whether the generator is executing.
    //  y       An iterator to delegate for a yield*.
    //  t       A temporary variable that holds one of the following values (note that these
    //          cases do not overlap):
    //          - The completion value when resuming from a `yield` or `yield*`.
    //          - The error value for a catch block.
    //          - The current protected region (array of try/catch/finally/end labels).
    //          - The verb (`next`, `throw`, or `return` method) to delegate to the expression
    //            of a `yield*`.
    //          - The result of evaluating the verb delegated to the expression of a `yield*`.
    //
    // functions:
    //  verb(n)     Creates a bound callback to the `step` function for opcode `n`.
    //  step(op)    Evaluates opcodes in a generator body until execution is suspended or
    //              completed.
    //
    // The __generator helper understands a limited set of instructions:
    //  0: next(value?)     - Start or resume the generator with the specified value.
    //  1: throw(error)     - Resume the generator with an exception. If the generator is
    //                        suspended inside of one or more protected regions, evaluates
    //                        any intervening finally blocks between the current label and
    //                        the nearest catch block or function boundary. If uncaught, the
    //                        exception is thrown to the caller.
    //  2: return(value?)   - Resume the generator as if with a return. If the generator is
    //                        suspended inside of one or more protected regions, evaluates any
    //                        intervening finally blocks.
    //  3: break(label)     - Jump to the specified label. If the label is outside of the
    //                        current protected region, evaluates any intervening finally
    //                        blocks.
    //  4: yield(value?)    - Yield execution to the caller with an optional value. When
    //                        resumed, the generator will continue at the next label.
    //  5: yield*(value)    - Delegates evaluation to the supplied iterator. When
    //                        delegation completes, the generator will continue at the next
    //                        label.
    //  6: catch(error)     - Handles an exception thrown from within the generator body. If
    //                        the current label is inside of one or more protected regions,
    //                        evaluates any intervening finally blocks between the current
    //                        label and the nearest catch block or function boundary. If
    //                        uncaught, the exception is thrown to the caller.
    //  7: endfinally       - Ends a finally block, resuming the last instruction prior to
    //                        entering a finally block.
    //
    // For examples of how these are used, see the comments in ./transformers/generators.ts
    var generatorHelper = {
        name: "typescript:generator",
        scoped: false,
        priority: 6,
        text: "\n            var __generator = (this && this.__generator) || function (thisArg, body) {\n                var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n                return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n                function verb(n) { return function (v) { return step([n, v]); }; }\n                function step(op) {\n                    if (f) throw new TypeError(\"Generator is already executing.\");\n                    while (_) try {\n                        if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n                        if (y = 0, t) op = [0, t.value];\n                        switch (op[0]) {\n                            case 0: case 1: t = op; break;\n                            case 4: _.label++; return { value: op[1], done: false };\n                            case 5: _.label++; y = op[1]; op = [0]; continue;\n                            case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                            default:\n                                if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                                if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                                if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                                if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                                if (t[2]) _.ops.pop();\n                                _.trys.pop(); continue;\n                        }\n                        op = body.call(thisArg, _);\n                    } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n                    if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n                }\n            };"
    };
})(ts || (ts = {}));
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/// <reference path="../destructuring.ts" />
/*@internal*/
var ts;
(function (ts) {
    function transformModule(context) {
        function getTransformModuleDelegate(moduleKind) {
            switch (moduleKind) {
                case ts.ModuleKind.AMD: return transformAMDModule;
                case ts.ModuleKind.UMD: return transformUMDModule;
                default: return transformCommonJSModule;
            }
        }
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(71 /* Identifier */); // Substitutes expression identifiers with imported/exported symbols.
        context.enableSubstitution(194 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(192 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(193 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(262 /* ShorthandPropertyAssignment */); // Substitutes shorthand property assignments for imported/exported symbols.
        context.enableEmitNotification(265 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var currentSourceFile; // The current file.
        var currentModuleInfo; // The ExternalModuleInfo for the current file.
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        var needUMDDynamicImportHelper;
        return transformSourceFile;
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile || !(ts.isExternalModule(node) || compilerOptions.isolatedModules || node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
                return node;
            }
            currentSourceFile = node;
            currentModuleInfo = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            moduleInfoMap[ts.getOriginalNodeId(node)] = currentModuleInfo;
            // Perform the transformation.
            var transformModule = getTransformModuleDelegate(moduleKind);
            var updated = transformModule(node);
            currentSourceFile = undefined;
            currentModuleInfo = undefined;
            needUMDDynamicImportHelper = false;
            return ts.aggregateTransformFlags(updated);
        }
        function shouldEmitUnderscoreUnderscoreESModule() {
            if (!currentModuleInfo.exportEquals && ts.isExternalModule(currentSourceFile)) {
                return true;
            }
            return false;
        }
        /**
         * Transforms a SourceFile into a CommonJS module.
         *
         * @param node The SourceFile node.
         */
        function transformCommonJSModule(node) {
            startLexicalEnvironment();
            var statements = [];
            var ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
            ts.addRange(statements, endLexicalEnvironment());
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
            if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
                // If we have any `export * from ...` declarations
                // we need to inform the emitter to add the __export helper.
                ts.addEmitHelper(updated, exportStarHelper);
            }
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into an AMD module.
         *
         * @param node The SourceFile node.
         */
        function transformAMDModule(node) {
            var define = ts.createIdentifier("define");
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            // An AMD define function has the following shape:
            //
            //     define(id?, dependencies?, factory);
            //
            // This has the shape of the following:
            //
            //     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
            //
            //     /// <amd-dependency path= "a.css" />
            //
            // we need to add modules without alias names to the end of the dependencies list
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ true), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            // Create an updated SourceFile:
            //
            //     define(moduleName?, ["module1", "module2"], function ...
            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createStatement(ts.createCall(define, 
                /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([
                    // Add the dependency array argument:
                    //
                    //     ["require", "exports", module1", "module2", ...]
                    ts.createArrayLiteral([
                        ts.createLiteral("require"),
                        ts.createLiteral("exports")
                    ].concat(aliasedModuleNames, unaliasedModuleNames)),
                    // Add the module body function argument:
                    //
                    //     function (require, exports, module1, module2) ...
                    ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, [
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                    ].concat(importAliasNames), 
                    /*type*/ undefined, transformAsynchronousModuleBody(node))
                ])))
            ]), 
            /*location*/ node.statements));
        }
        /**
         * Transforms a SourceFile into a UMD module.
         *
         * @param node The SourceFile node.
         */
        function transformUMDModule(node) {
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var umdHeader = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], 
            /*type*/ undefined, ts.setTextRange(ts.createBlock([
                ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("module"), "object"), ts.createTypeCheck(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), "object")), ts.createBlock([
                    ts.createVariableStatement(
                    /*modifiers*/ undefined, [
                        ts.createVariableDeclaration("v", 
                        /*type*/ undefined, ts.createCall(ts.createIdentifier("factory"), 
                        /*typeArguments*/ undefined, [
                            ts.createIdentifier("require"),
                            ts.createIdentifier("exports")
                        ]))
                    ]),
                    ts.setEmitFlags(ts.createIf(ts.createStrictInequality(ts.createIdentifier("v"), ts.createIdentifier("undefined")), ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), ts.createIdentifier("v")))), 1 /* SingleLine */)
                ]), ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("define"), "function"), ts.createPropertyAccess(ts.createIdentifier("define"), "amd")), ts.createBlock([
                    ts.createStatement(ts.createCall(ts.createIdentifier("define"), 
                    /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([
                        ts.createArrayLiteral([
                            ts.createLiteral("require"),
                            ts.createLiteral("exports")
                        ].concat(aliasedModuleNames, unaliasedModuleNames)),
                        ts.createIdentifier("factory")
                    ])))
                ])))
            ], 
            /*multiLine*/ true), 
            /*location*/ undefined));
            // Create an updated SourceFile:
            //
            //  (function (factory) {
            //      if (typeof module === "object" && typeof module.exports === "object") {
            //          var v = factory(require, exports);
            //          if (v !== undefined) module.exports = v;
            //      }
            //      else if (typeof define === 'function' && define.amd) {
            //          define(["require", "exports"], factory);
            //      }
            //  })(function ...)
            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createStatement(ts.createCall(umdHeader, 
                /*typeArguments*/ undefined, [
                    // Add the module body function argument:
                    //
                    //     function (require, exports) ...
                    ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, [
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                    ].concat(importAliasNames), 
                    /*type*/ undefined, transformAsynchronousModuleBody(node))
                ]))
            ]), 
            /*location*/ node.statements));
        }
        /**
         * Collect the additional asynchronous dependencies for the module.
         *
         * @param node The source file.
         * @param includeNonAmdDependencies A value indicating whether to include non-AMD dependencies.
         */
        function collectAsynchronousDependencies(node, includeNonAmdDependencies) {
            // names of modules with corresponding parameter in the factory function
            var aliasedModuleNames = [];
            // names of modules with no corresponding parameters in factory function
            var unaliasedModuleNames = [];
            // names of the parameters in the factory function; these
            // parameters need to match the indexes of the corresponding
            // module names in aliasedModuleNames.
            var importAliasNames = [];
            // 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(ts.createLiteral(amdDependency.path));
                    importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name));
                }
                else {
                    unaliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                }
            }
            for (var _b = 0, _c = currentModuleInfo.externalImports; _b < _c.length; _b++) {
                var importNode = _c[_b];
                // Find the name of the external module
                var externalModuleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
                // Find the name of the module alias, if there is one
                var importAliasName = ts.getLocalNameForExternalImport(importNode, currentSourceFile);
                // It is possible that externalModuleName is undefined if it is not string literal.
                // This can happen in the invalid import syntax.
                // E.g : "import * from alias from 'someLib';"
                if (externalModuleName) {
                    if (includeNonAmdDependencies && importAliasName) {
                        // Set emitFlags on the name of the classDeclaration
                        // This is so that when printer will not substitute the identifier
                        ts.setEmitFlags(importAliasName, 4 /* NoSubstitution */);
                        aliasedModuleNames.push(externalModuleName);
                        importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
                    }
                    else {
                        unaliasedModuleNames.push(externalModuleName);
                    }
                }
            }
            return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
        }
        /**
         * Transforms a SourceFile into an AMD or UMD module body.
         *
         * @param node The SourceFile node.
         */
        function transformAsynchronousModuleBody(node) {
            startLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            // Visit each statement of the module body.
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            // Append the 'export =' statement if provided.
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
            // End the lexical environment for the module body
            // and merge any new lexical declarations.
            ts.addRange(statements, endLexicalEnvironment());
            var body = ts.createBlock(statements, /*multiLine*/ true);
            if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
                // If we have any `export * from ...` declarations
                // we need to inform the emitter to add the __export helper.
                ts.addEmitHelper(body, exportStarHelper);
            }
            if (needUMDDynamicImportHelper) {
                ts.addEmitHelper(body, dynamicImportUMDHelper);
            }
            return body;
        }
        /**
         * Adds the down-level representation of `export=` to the statement list if one exists
         * in the source file.
         *
         * @param statements The Statement list to modify.
         * @param emitAsReturn A value indicating whether to emit the `export=` statement as a
         * return statement.
         */
        function addExportEqualsIfNeeded(statements, emitAsReturn) {
            if (currentModuleInfo.exportEquals) {
                var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, importCallExpressionVisitor);
                if (expressionResult) {
                    if (emitAsReturn) {
                        var statement = ts.createReturn(expressionResult);
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
                        statements.push(statement);
                    }
                    else {
                        var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 1536 /* NoComments */);
                        statements.push(statement);
                    }
                }
            }
        }
        //
        // Top-Level Source Element Visitors
        //
        /**
         * Visits a node at the top level of the source file.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 238 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 244 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                case 243 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 208 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 229 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 290 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 291 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return ts.visitEachChild(node, importCallExpressionVisitor, context);
            }
        }
        function importCallExpressionVisitor(node) {
            // This visitor does not need to descend into the tree if there is no dynamic import,
            // as export/import statements are only transformed at the top level of a file.
            if (!(node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
                return node;
            }
            if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else {
                return ts.visitEachChild(node, importCallExpressionVisitor, context);
            }
        }
        function visitImportCallExpression(node) {
            var argument = ts.visitNode(ts.firstOrUndefined(node.arguments), importCallExpressionVisitor);
            var containsLexicalThis = !!(node.transformFlags & 16384 /* ContainsLexicalThis */);
            switch (compilerOptions.module) {
                case ts.ModuleKind.AMD:
                    return createImportCallExpressionAMD(argument, containsLexicalThis);
                case ts.ModuleKind.UMD:
                    return createImportCallExpressionUMD(argument, containsLexicalThis);
                case ts.ModuleKind.CommonJS:
                default:
                    return createImportCallExpressionCommonJS(argument, containsLexicalThis);
            }
        }
        function createImportCallExpressionUMD(arg, containsLexicalThis) {
            // (function (factory) {
            //      ... (regular UMD)
            // }
            // })(function (require, exports, useSyncRequire) {
            //      "use strict";
            //      Object.defineProperty(exports, "__esModule", { value: true });
            //      var __syncRequire = typeof module === "object" && typeof module.exports === "object";
            //      var __resolved = new Promise(function (resolve) { resolve(); });
            //      .....
            //      __syncRequire
            //          ? __resolved.then(function () { return require(x); }) /*CommonJs Require*/
            //          : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            needUMDDynamicImportHelper = true;
            if (ts.isSimpleCopiableExpression(arg)) {
                var argClone = ts.isGeneratedIdentifier(arg) ? arg : ts.isStringLiteral(arg) ? ts.createLiteral(arg) : ts.setEmitFlags(ts.setTextRange(ts.getSynthesizedClone(arg), arg), 1536 /* NoComments */);
                return ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis));
            }
            else {
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                return ts.createComma(ts.createAssignment(temp, arg), ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis)));
            }
        }
        function createImportCallExpressionAMD(arg, containsLexicalThis) {
            // improt("./blah")
            // emit as
            // define(["require", "exports", "blah"], function (require, exports) {
            //     ...
            //     new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            var resolve = ts.createUniqueName("resolve");
            var reject = ts.createUniqueName("reject");
            var parameters = [
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)
            ];
            var body = ts.createBlock([
                ts.createStatement(ts.createCall(ts.createIdentifier("require"), 
                /*typeArguments*/ undefined, [ts.createArrayLiteral([arg || ts.createOmittedExpression()]), resolve, reject]))
            ]);
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, body);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, body);
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            return ts.createNew(ts.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
        }
        function createImportCallExpressionCommonJS(arg, containsLexicalThis) {
            // import("./blah")
            // emit as
            // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/
            // We have to wrap require in then callback so that require is done in asynchronously
            // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
            var promiseResolveCall = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
            var requireCall = ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, requireCall);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock([ts.createReturn(requireCall)]));
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            return ts.createCall(ts.createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (!node.importClause) {
                    // import "mod";
                    return ts.setTextRange(ts.createStatement(createRequireCall(node)), node);
                }
                else {
                    var variables = [];
                    if (namespaceDeclaration && !ts.isDefaultImport(node)) {
                        // import * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                        /*type*/ undefined, createRequireCall(node)));
                    }
                    else {
                        // import d from "mod";
                        // import { x, y } from "mod";
                        // import d, { x, y } from "mod";
                        // import d, * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getGeneratedNameForNode(node), 
                        /*type*/ undefined, createRequireCall(node)));
                        if (namespaceDeclaration && ts.isDefaultImport(node)) {
                            variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                            /*type*/ undefined, ts.getGeneratedNameForNode(node)));
                        }
                    }
                    statements = ts.append(statements, ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(variables, languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), 
                    /*location*/ node));
                }
            }
            else if (namespaceDeclaration && ts.isDefaultImport(node)) {
                // import d, * as n from "mod";
                statements = ts.append(statements, ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.setTextRange(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                    /*type*/ undefined, ts.getGeneratedNameForNode(node)), 
                    /*location*/ node)
                ], languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Creates a `require()` call to import an external module.
         *
         * @param importNode The declararation to import.
         */
        function createRequireCall(importNode) {
            var moduleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
            var args = [];
            if (moduleName) {
                args.push(moduleName);
            }
            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, args);
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setTextRange(ts.createStatement(createExportExpression(node.name, createRequireCall(node))), node));
                }
                else {
                    statements = ts.append(statements, ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(ts.getSynthesizedClone(node.name), 
                        /*type*/ undefined, createRequireCall(node))
                    ], 
                    /*flags*/ languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), node));
                }
            }
            else {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setTextRange(ts.createStatement(createExportExpression(ts.getExportName(node), ts.getLocalName(node))), node));
                }
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportDeclaration node.
         *
         * @param The node to visit.
         */
        function visitExportDeclaration(node) {
            if (!node.moduleSpecifier) {
                // Elide export declarations with no module specifier as they are handled
                // elsewhere.
                return undefined;
            }
            var generatedName = ts.getGeneratedNameForNode(node);
            if (node.exportClause) {
                var statements = [];
                // export { x, y } from "mod";
                if (moduleKind !== ts.ModuleKind.AMD) {
                    statements.push(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(generatedName, 
                        /*type*/ undefined, createRequireCall(node))
                    ])), 
                    /*location*/ node));
                }
                for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) {
                    var specifier = _a[_i];
                    var exportedValue = ts.createPropertyAccess(generatedName, specifier.propertyName || specifier.name);
                    statements.push(ts.setTextRange(ts.createStatement(createExportExpression(ts.getExportName(specifier), exportedValue)), specifier));
                }
                return ts.singleOrMany(statements);
            }
            else {
                // export * from "mod";
                return ts.setTextRange(ts.createStatement(createExportStarHelper(context, moduleKind !== ts.ModuleKind.AMD ? createRequireCall(node) : generatedName)), node);
            }
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                return undefined;
            }
            var statements;
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), ts.visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true);
            }
            else {
                statements = appendExportStatement(statements, ts.createIdentifier("default"), ts.visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, importCallExpressionVisitor), 
                /*type*/ undefined, ts.visitEachChild(node.body, importCallExpressionVisitor, context)), 
                /*location*/ node), 
                /*original*/ node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createClassDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, importCallExpressionVisitor), ts.visitNodes(node.members, importCallExpressionVisitor)), node), node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a VariableStatement node.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            var statements;
            var variables;
            var expressions;
            if (ts.hasModifier(node, 1 /* Export */)) {
                var modifiers = void 0;
                // If we're exporting these variables, then these just become assignments to 'exports.x'.
                // We only want to emit assignments for variables with initializers.
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) {
                        if (!modifiers) {
                            modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier);
                        }
                        variables = ts.append(variables, variable);
                    }
                    else if (variable.initializer) {
                        expressions = ts.append(expressions, transformInitializedVariable(variable));
                    }
                }
                if (variables) {
                    statements = ts.append(statements, ts.updateVariableStatement(node, modifiers, ts.updateVariableDeclarationList(node.declarationList, variables)));
                }
                if (expressions) {
                    statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.inlineExpressions(expressions)), node));
                }
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Transforms an exported variable with an initializer into an expression.
         *
         * @param node The node to transform.
         */
        function transformInitializedVariable(node) {
            if (ts.isBindingPattern(node.name)) {
                return ts.flattenDestructuringAssignment(ts.visitNode(node, importCallExpressionVisitor), 
                /*visitor*/ undefined, context, 0 /* All */, 
                /*needsValue*/ false, createExportExpression);
            }
            else {
                return ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), node.name), 
                /*location*/ node.name), ts.visitNode(node.initializer, importCallExpressionVisitor));
            }
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, add the exports of the elided variable
            // statement.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 208 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 240 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 241 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the exports of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         */
        function appendExportsOfVariableStatement(statements, node) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                statements = appendExportsOfBindingElement(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfBindingElement(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         */
        function appendExportsOfDeclaration(statements, decl) {
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = currentModuleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_1 = exportSpecifiers; _i < exportSpecifiers_1.length; _i++) {
                    var exportSpecifier = exportSpecifiers_1[_i];
                    statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, location, allowComments) {
            statements = ts.append(statements, createExportStatement(exportName, expression, location, allowComments));
            return statements;
        }
        function createUnderscoreUnderscoreESModule() {
            var statement;
            if (languageVersion === 0 /* ES3 */) {
                statement = ts.createStatement(createExportExpression(ts.createIdentifier("__esModule"), ts.createLiteral(/*value*/ true)));
            }
            else {
                statement = ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
                /*typeArguments*/ undefined, [
                    ts.createIdentifier("exports"),
                    ts.createLiteral("__esModule"),
                    ts.createObjectLiteral([
                        ts.createPropertyAssignment("value", ts.createLiteral(/*value*/ true))
                    ])
                ]));
            }
            ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, location, allowComments) {
            var statement = ts.setTextRange(ts.createStatement(createExportExpression(name, value)), location);
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         */
        function createExportExpression(name, value, location) {
            return ts.setTextRange(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(name)), value), location);
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            // Elide module-specific modifiers.
            switch (node.kind) {
                case 84 /* ExportKeyword */:
                case 79 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 265 /* SourceFile */) {
                currentSourceFile = node;
                currentModuleInfo = moduleInfoMap[ts.getOriginalNodeId(currentSourceFile)];
                noSubstitution = [];
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                currentModuleInfo = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (node.id && noSubstitution[node.id]) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose declaration name is an imported
         * or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            var exportedOrImportedName = substituteExpressionIdentifier(name);
            if (exportedOrImportedName !== name) {
                // A shorthand property with an assignment initializer is probably part of a
                // destructuring assignment
                if (node.objectAssignmentInitializer) {
                    var initializer = ts.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
                    return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                }
                return ts.setTextRange(ts.createPropertyAssignment(name, exportedOrImportedName), node);
            }
            return node;
        }
        /**
         * Substitution for an Expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 194 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 193 /* PostfixUnaryExpression */:
                case 192 /* PrefixUnaryExpression */:
                    return substituteUnaryExpression(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported
         * symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var exportContainer = resolver.getReferencedExportContainer(node, ts.isExportName(node));
                if (exportContainer && exportContainer.kind === 265 /* SourceFile */) {
                    return ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(node)), 
                    /*location*/ node);
                }
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        var name = importDeclaration.propertyName || importDeclaration.name;
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_1 = exportedNames; _i < exportedNames_1.length; _i++) {
                        var exportName = exportedNames_1[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression, /*location*/ node);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 193 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createBinary(node.operand, ts.createToken(node.operator === 43 /* PlusPlusToken */ ? 59 /* PlusEqualsToken */ : 60 /* MinusEqualsToken */), ts.createLiteral(1)), 
                        /*location*/ node)
                        : node;
                    for (var _i = 0, exportedNames_2 = exportedNames; _i < exportedNames_2.length; _i++) {
                        var exportName = exportedNames_2[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Gets the additional exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    return currentModuleInfo
                        && currentModuleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)];
                }
            }
        }
    }
    ts.transformModule = transformModule;
    // emit output for the __export helper function
    var exportStarHelper = {
        name: "typescript:export-star",
        scoped: true,
        text: "\n            function __export(m) {\n                for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n            }\n        "
    };
    function createExportStarHelper(context, module) {
        var compilerOptions = context.getCompilerOptions();
        return compilerOptions.importHelpers
            ? ts.createCall(ts.getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, ts.createIdentifier("exports")])
            : ts.createCall(ts.createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
    }
    // emit helper for dynamic import
    var dynamicImportUMDHelper = {
        name: "typescript:dynamicimport-sync-require",
        scoped: true,
        text: "\n            var __syncRequire = typeof module === \"object\" && typeof module.exports === \"object\";"
    };
})(ts || (ts = {}));
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/// <reference path="../destructuring.ts" />
/*@internal*/
var ts;
(function (ts) {
    function transformSystemModule(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(71 /* Identifier */); // Substitutes expression identifiers for imported symbols.
        context.enableSubstitution(194 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(192 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(193 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableEmitNotification(265 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var exportFunctionsMap = []; // The export function associated with a source file.
        var noSubstitutionMap = []; // Set of nodes for which substitution rules should be ignored for each file.
        var currentSourceFile; // The current file.
        var moduleInfo; // ExternalModuleInfo for the current file.
        var exportFunction; // The export function for the current file.
        var contextObject; // The context object for the current file.
        var hoistedStatements;
        var enclosingBlockScopedContainer;
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        return transformSourceFile;
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
                return node;
            }
            var id = ts.getOriginalNodeId(node);
            currentSourceFile = node;
            enclosingBlockScopedContainer = node;
            // System modules have the following shape:
            //
            //     System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
            //
            // The parameter 'exports' here is a callback '<T>(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 'substitutePostfixUnaryExpression' for more details
            // Collect information about the external module and dependency groups.
            moduleInfo = moduleInfoMap[id] = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            // Make sure that the name of the 'exports' function does not conflict with
            // existing identifiers.
            exportFunction = ts.createUniqueName("exports");
            exportFunctionsMap[id] = exportFunction;
            contextObject = ts.createUniqueName("context");
            // Add the body of the module.
            var dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
            var moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
            var moduleBodyFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction),
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject)
            ], 
            /*type*/ undefined, moduleBodyBlock);
            // Write the call to `System.register`
            // Clear the emit-helpers flag for later passes since we'll have already used it in the module body
            // So the helper will be emit at the correct position instead of at the top of the source-file
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var dependencies = ts.createArrayLiteral(ts.map(dependencyGroups, function (dependencyGroup) { return dependencyGroup.name; }));
            var updated = ts.setEmitFlags(ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("System"), "register"), 
                /*typeArguments*/ undefined, moduleName
                    ? [moduleName, dependencies, moduleBodyFunction]
                    : [dependencies, moduleBodyFunction]))
            ]), node.statements)), 1024 /* NoTrailingComments */);
            if (!(compilerOptions.outFile || compilerOptions.out)) {
                ts.moveEmitHelpers(updated, moduleBodyBlock, function (helper) { return !helper.scoped; });
            }
            if (noSubstitution) {
                noSubstitutionMap[id] = noSubstitution;
                noSubstitution = undefined;
            }
            currentSourceFile = undefined;
            moduleInfo = undefined;
            exportFunction = undefined;
            contextObject = undefined;
            hoistedStatements = undefined;
            enclosingBlockScopedContainer = undefined;
            return ts.aggregateTransformFlags(updated);
        }
        /**
         * Collects the dependency groups for this files imports.
         *
         * @param externalImports The imports for the file.
         */
        function collectDependencyGroups(externalImports) {
            var groupIndices = ts.createMap();
            var dependencyGroups = [];
            for (var i = 0; i < externalImports.length; i++) {
                var externalImport = externalImports[i];
                var externalModuleName = ts.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
                if (externalModuleName) {
                    var text = externalModuleName.text;
                    var groupIndex = groupIndices.get(text);
                    if (groupIndex !== undefined) {
                        // deduplicate/group entries in dependency list by the dependency name
                        dependencyGroups[groupIndex].externalImports.push(externalImport);
                    }
                    else {
                        groupIndices.set(text, dependencyGroups.length);
                        dependencyGroups.push({
                            name: externalModuleName,
                            externalImports: [externalImport]
                        });
                    }
                }
            }
            return dependencyGroups;
        }
        /**
         * Adds the statements for the module body function for the source file.
         *
         * @param node The source file for the module.
         * @param dependencyGroups The grouped dependencies of the module.
         */
        function createSystemModuleBody(node, dependencyGroups) {
            // Shape of the body in system modules:
            //
            //  function (exports) {
            //      <list of local aliases for imports>
            //      <hoisted variable declarations>
            //      <hoisted function declarations>
            //      return {
            //          setters: [
            //              <list of setter function for imports>
            //          ],
            //          execute: function() {
            //              <module statements>
            //          }
            //      }
            //      <temp declarations>
            //  }
            //
            // i.e:
            //
            //   import {x} from 'file1'
            //   var y = 1;
            //   export function foo() { return y + x(); }
            //   console.log(y);
            //
            // Will be transformed to:
            //
            //  function(exports) {
            //      function foo() { return y + file_1.x(); }
            //      exports("foo", foo);
            //      var file_1, y;
            //      return {
            //          setters: [
            //              function(v) { file_1 = v }
            //          ],
            //          execute(): function() {
            //              y = 1;
            //              console.log(y);
            //          }
            //      };
            //  }
            var statements = [];
            // We start a new lexical environment in this function body, but *not* in the
            // body of the execute function. This allows us to emit temporary declarations
            // only in the outer module body and not in the inner one.
            startLexicalEnvironment();
            // Add any prologue directives.
            var ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
            // var __moduleName = context_1 && context_1.id;
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration("__moduleName", 
                /*type*/ undefined, ts.createLogicalAnd(contextObject, ts.createPropertyAccess(contextObject, "id")))
            ])));
            // Visit the synthetic external helpers import declaration if present
            ts.visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement);
            // Visit the statements of the source file, emitting any transformations into
            // the `executeStatements` array. We do this *before* we fill the `setters` array
            // as we both emit transformations as well as aggregate some data used when creating
            // setters. This allows us to reduce the number of times we need to loop through the
            // statements of the source file.
            var executeStatements = ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset);
            // Emit early exports for function declarations.
            ts.addRange(statements, hoistedStatements);
            // We emit hoisted variables early to align roughly with our previous emit output.
            // Two key differences in this approach are:
            // - Temporary variables will appear at the top rather than at the bottom of the file
            ts.addRange(statements, endLexicalEnvironment());
            var exportStarFunction = addExportStarIfNeeded(statements);
            var moduleObject = ts.createObjectLiteral([
                ts.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)),
                ts.createPropertyAssignment("execute", ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock(executeStatements, /*multiLine*/ true)))
            ]);
            moduleObject.multiLine = true;
            statements.push(ts.createReturn(moduleObject));
            return ts.createBlock(statements, /*multiLine*/ true);
        }
        /**
         * Adds an exportStar function to a statement list if it is needed for the file.
         *
         * @param statements A statement list.
         */
        function addExportStarIfNeeded(statements) {
            if (!moduleInfo.hasExportStarsToExportValues) {
                return;
            }
            // when resolving exports local exported entries/indirect exported entries in the module
            // should always win over entries with similar names that were added via star exports
            // to support this we store names of local/indirect exported entries in a set.
            // this set is used to filter names brought by star expors.
            // local names set should only be added if we have anything exported
            if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) {
                // no exported declarations (export var ...) or export specifiers (export {x})
                // check if we have any non star export declarations.
                var hasExportDeclarationWithExportClause = false;
                for (var _i = 0, _a = moduleInfo.externalImports; _i < _a.length; _i++) {
                    var externalImport = _a[_i];
                    if (externalImport.kind === 244 /* ExportDeclaration */ && externalImport.exportClause) {
                        hasExportDeclarationWithExportClause = true;
                        break;
                    }
                }
                if (!hasExportDeclarationWithExportClause) {
                    // we still need to emit exportStar helper
                    var exportStarFunction_1 = createExportStarFunction(/*localNames*/ undefined);
                    statements.push(exportStarFunction_1);
                    return exportStarFunction_1.name;
                }
            }
            var exportedNames = [];
            if (moduleInfo.exportedNames) {
                for (var _b = 0, _c = moduleInfo.exportedNames; _b < _c.length; _b++) {
                    var exportedLocalName = _c[_b];
                    if (exportedLocalName.escapedText === "default") {
                        continue;
                    }
                    // write name of exported declaration, i.e 'export var x...'
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(exportedLocalName), ts.createTrue()));
                }
            }
            for (var _d = 0, _e = moduleInfo.externalImports; _d < _e.length; _d++) {
                var externalImport = _e[_d];
                if (externalImport.kind !== 244 /* ExportDeclaration */) {
                    continue;
                }
                var exportDecl = externalImport;
                if (!exportDecl.exportClause) {
                    // export * from ...
                    continue;
                }
                for (var _f = 0, _g = exportDecl.exportClause.elements; _f < _g.length; _f++) {
                    var element = _g[_f];
                    // write name of indirectly exported entry, i.e. 'export {x} from ...'
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(element.name || element.propertyName)), ts.createTrue()));
                }
            }
            var exportedNamesStorageRef = ts.createUniqueName("exportedNames");
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(exportedNamesStorageRef, 
                /*type*/ undefined, ts.createObjectLiteral(exportedNames, /*multiline*/ true))
            ])));
            var exportStarFunction = createExportStarFunction(exportedNamesStorageRef);
            statements.push(exportStarFunction);
            return exportStarFunction.name;
        }
        /**
         * Creates an exportStar function for the file, with an optional set of excluded local
         * names.
         *
         * @param localNames An optional reference to an object containing a set of excluded local
         * names.
         */
        function createExportStarFunction(localNames) {
            var exportStarFunction = ts.createUniqueName("exportStar");
            var m = ts.createIdentifier("m");
            var n = ts.createIdentifier("n");
            var exports = ts.createIdentifier("exports");
            var condition = ts.createStrictInequality(n, ts.createLiteral("default"));
            if (localNames) {
                condition = ts.createLogicalAnd(condition, ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(localNames, "hasOwnProperty"), 
                /*typeArguments*/ undefined, [n])));
            }
            return ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, exportStarFunction, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], 
            /*type*/ undefined, ts.createBlock([
                ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(exports, 
                    /*type*/ undefined, ts.createObjectLiteral([]))
                ])),
                ts.createForIn(ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(n, /*type*/ undefined)
                ]), m, ts.createBlock([
                    ts.setEmitFlags(ts.createIf(condition, ts.createStatement(ts.createAssignment(ts.createElementAccess(exports, n), ts.createElementAccess(m, n)))), 1 /* SingleLine */)
                ])),
                ts.createStatement(ts.createCall(exportFunction, 
                /*typeArguments*/ undefined, [exports]))
            ], /*multiline*/ true));
        }
        /**
         * Creates an array setter callbacks for each dependency group.
         *
         * @param exportStarFunction A reference to an exportStarFunction for the file.
         * @param dependencyGroups An array of grouped dependencies.
         */
        function createSettersArray(exportStarFunction, dependencyGroups) {
            var setters = [];
            for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) {
                var group = dependencyGroups_1[_i];
                // derive a unique name for parameter from the first named entry in the group
                var localName = ts.forEach(group.externalImports, function (i) { return ts.getLocalNameForExternalImport(i, currentSourceFile); });
                var parameterName = localName ? ts.getGeneratedNameForNode(localName) : ts.createUniqueName("");
                var statements = [];
                for (var _a = 0, _b = group.externalImports; _a < _b.length; _a++) {
                    var entry = _b[_a];
                    var importVariableName = ts.getLocalNameForExternalImport(entry, currentSourceFile);
                    switch (entry.kind) {
                        case 238 /* ImportDeclaration */:
                            if (!entry.importClause) {
                                // 'import "..."' case
                                // module is imported only for side-effects, no emit required
                                break;
                            }
                        // falls through
                        case 237 /* ImportEqualsDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            // save import into the local
                            statements.push(ts.createStatement(ts.createAssignment(importVariableName, parameterName)));
                            break;
                        case 244 /* ExportDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            if (entry.exportClause) {
                                //  export {a, b as c} from 'foo'
                                //
                                // emit as:
                                //
                                //  exports_({
                                //     "a": _["a"],
                                //     "c": _["b"]
                                //  });
                                var properties = [];
                                for (var _c = 0, _d = entry.exportClause.elements; _c < _d.length; _c++) {
                                    var e = _d[_c];
                                    properties.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(e.name)), ts.createElementAccess(parameterName, ts.createLiteral(ts.idText(e.propertyName || e.name)))));
                                }
                                statements.push(ts.createStatement(ts.createCall(exportFunction, 
                                /*typeArguments*/ undefined, [ts.createObjectLiteral(properties, /*multiline*/ true)])));
                            }
                            else {
                                //  export * from 'foo'
                                //
                                // emit as:
                                //
                                //  exportStar(foo_1_1);
                                statements.push(ts.createStatement(ts.createCall(exportStarFunction, 
                                /*typeArguments*/ undefined, [parameterName])));
                            }
                            break;
                    }
                }
                setters.push(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
                /*type*/ undefined, ts.createBlock(statements, /*multiLine*/ true)));
            }
            return ts.createArrayLiteral(setters, /*multiLine*/ true);
        }
        //
        // Top-level Source Element Visitors
        //
        /**
         * Visit source elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 238 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 244 /* ExportDeclaration */:
                    // ExportDeclarations are elided as they are handled via
                    // `appendExportsOfDeclaration`.
                    return undefined;
                case 243 /* ExportAssignment */:
                    return visitExportAssignment(node);
                default:
                    return nestedElementVisitor(node);
            }
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            if (node.importClause) {
                hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile));
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                // Elide `export=` as it is illegal in a SystemJS module.
                return undefined;
            }
            var expression = ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression);
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
            else {
                return createExportStatement(ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
        }
        /**
         * Visits a FunctionDeclaration, hoisting it to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            if (ts.hasModifier(node, 1 /* Export */)) {
                hoistedStatements = ts.append(hoistedStatements, ts.updateFunctionDeclaration(node, node.decorators, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, destructuringAndImportCallVisitor, ts.isParameterDeclaration), 
                /*type*/ undefined, ts.visitNode(node.body, destructuringAndImportCallVisitor, ts.isBlock)));
            }
            else {
                hoistedStatements = ts.append(hoistedStatements, ts.visitEachChild(node, destructuringAndImportCallVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
            }
            return undefined;
        }
        /**
         * Visits a ClassDeclaration, hoisting its name to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            // Hoist the name of the class declaration to the outer module body function.
            var name = ts.getLocalName(node);
            hoistVariableDeclaration(name);
            // Rewrite the class declaration into an assignment of a class expression.
            statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.createAssignment(name, ts.setTextRange(ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, destructuringAndImportCallVisitor, ts.isHeritageClause), ts.visitNodes(node.members, destructuringAndImportCallVisitor, ts.isClassElement)), node))), node));
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a variable statement, hoisting declared names to the top-level module body.
         * Each declaration is rewritten into an assignment expression.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (!shouldHoistVariableDeclarationList(node.declarationList)) {
                return ts.visitNode(node, destructuringAndImportCallVisitor, ts.isStatement);
            }
            var expressions;
            var isExportedDeclaration = ts.hasModifier(node, 1 /* Export */);
            var isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node);
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                if (variable.initializer) {
                    expressions = ts.append(expressions, transformInitializedVariable(variable, isExportedDeclaration && !isMarkedDeclaration));
                }
                else {
                    hoistBindingElement(variable);
                }
            }
            var statements;
            if (expressions) {
                statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.inlineExpressions(expressions)), node));
            }
            if (isMarkedDeclaration) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Hoists the declared names of a VariableDeclaration or BindingElement.
         *
         * @param node The declaration to hoist.
         */
        function hoistBindingElement(node) {
            if (ts.isBindingPattern(node.name)) {
                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistBindingElement(element);
                    }
                }
            }
            else {
                hoistVariableDeclaration(ts.getSynthesizedClone(node.name));
            }
        }
        /**
         * Determines whether a VariableDeclarationList should be hoisted.
         *
         * @param node The node to test.
         */
        function shouldHoistVariableDeclarationList(node) {
            // hoist only non-block scoped declarations or block scoped declarations parented by source file
            return (ts.getEmitFlags(node) & 2097152 /* NoHoisting */) === 0
                && (enclosingBlockScopedContainer.kind === 265 /* SourceFile */
                    || (ts.getOriginalNode(node).flags & 3 /* BlockScoped */) === 0);
        }
        /**
         * Transform an initialized variable declaration into an expression.
         *
         * @param node The node to transform.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function transformInitializedVariable(node, isExportedDeclaration) {
            var createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
            return ts.isBindingPattern(node.name)
                ? ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ false, createAssignment)
                : node.initializer ? createAssignment(node.name, ts.visitNode(node.initializer, destructuringAndImportCallVisitor, ts.isExpression)) : node.name;
        }
        /**
         * Creates an assignment expression for an exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ true);
        }
        /**
         * Creates an assignment expression for a non-exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createNonExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ false);
        }
        /**
         * Creates an assignment expression for a variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function createVariableAssignment(name, value, location, isExportedDeclaration) {
            hoistVariableDeclaration(ts.getSynthesizedClone(name));
            return isExportedDeclaration
                ? createExportExpression(name, preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location)))
                : preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location));
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, we defer the exports of the elided variable
            // statement until we visit this declaration's `EndOfDeclarationMarker`.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 208 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                var isExportedDeclaration = ts.hasModifier(node.original, 1 /* Export */);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 240 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 241 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the export of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export each VariableDeclaration of
         * `nodes` declaration list.
         */
        function appendExportsOfVariableStatement(statements, node, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.initializer || exportSelf) {
                    statements = appendExportsOfBindingElement(statements, decl, exportSelf);
                }
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export the declaration itself.
         */
        function appendExportsOfBindingElement(statements, decl, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element, exportSelf);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                var excludeName = void 0;
                if (exportSelf) {
                    statements = appendExportStatement(statements, decl.name, ts.getLocalName(decl));
                    excludeName = ts.idText(decl.name);
                }
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var excludeName;
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createLiteral("default") : decl.name;
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl));
                excludeName = ts.getTextOfIdentifierOrLiteral(exportName);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         * @param excludeName An optional name to exclude from exports.
         */
        function appendExportsOfDeclaration(statements, decl, excludeName) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = moduleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_2 = exportSpecifiers; _i < exportSpecifiers_2.length; _i++) {
                    var exportSpecifier = exportSpecifiers_2[_i];
                    if (exportSpecifier.name.escapedText !== excludeName) {
                        statements = appendExportStatement(statements, exportSpecifier.name, name);
                    }
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, allowComments) {
            statements = ts.append(statements, createExportStatement(exportName, expression, allowComments));
            return statements;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, allowComments) {
            var statement = ts.createStatement(createExportExpression(name, value));
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         */
        function createExportExpression(name, value) {
            var exportName = ts.isIdentifier(name) ? ts.createLiteral(name) : name;
            ts.setEmitFlags(value, ts.getEmitFlags(value) | 1536 /* NoComments */);
            return ts.setCommentRange(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
        }
        //
        // Top-Level or Nested Source Element Visitors
        //
        /**
         * Visit nested elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function nestedElementVisitor(node) {
            switch (node.kind) {
                case 208 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 228 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 229 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 214 /* ForStatement */:
                    return visitForStatement(node);
                case 215 /* ForInStatement */:
                    return visitForInStatement(node);
                case 216 /* ForOfStatement */:
                    return visitForOfStatement(node);
                case 212 /* DoStatement */:
                    return visitDoStatement(node);
                case 213 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 222 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 220 /* WithStatement */:
                    return visitWithStatement(node);
                case 221 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 235 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 257 /* CaseClause */:
                    return visitCaseClause(node);
                case 258 /* DefaultClause */:
                    return visitDefaultClause(node);
                case 224 /* TryStatement */:
                    return visitTryStatement(node);
                case 260 /* CatchClause */:
                    return visitCatchClause(node);
                case 207 /* Block */:
                    return visitBlock(node);
                case 290 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 291 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return destructuringAndImportCallVisitor(node);
            }
        }
        /**
         * Visits the body of a ForStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateFor(node, visitForInitializer(node.initializer), ts.visitNode(node.condition, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.incrementor, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForInStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForInStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForIn(node, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForOfStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForOfStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForOf(node, node.awaitModifier, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Determines whether to hoist the initializer of a ForStatement, ForInStatement, or
         * ForOfStatement.
         *
         * @param node The node to test.
         */
        function shouldHoistForInitializer(node) {
            return ts.isVariableDeclarationList(node)
                && shouldHoistVariableDeclarationList(node);
        }
        /**
         * Visits the initializer of a ForStatement, ForInStatement, or ForOfStatement
         *
         * @param node The node to visit.
         */
        function visitForInitializer(node) {
            if (!node) {
                return node;
            }
            if (shouldHoistForInitializer(node)) {
                var expressions = void 0;
                for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    expressions = ts.append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false));
                    if (!variable.initializer) {
                        hoistBindingElement(variable);
                    }
                }
                return expressions ? ts.inlineExpressions(expressions) : ts.createOmittedExpression();
            }
            else {
                return ts.visitEachChild(node, nestedElementVisitor, context);
            }
        }
        /**
         * Visits the body of a DoStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDoStatement(node) {
            return ts.updateDo(node, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression));
        }
        /**
         * Visits the body of a WhileStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWhileStatement(node) {
            return ts.updateWhile(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a LabeledStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitLabeledStatement(node) {
            return ts.updateLabel(node, node.label, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a WithStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWithStatement(node) {
            return ts.updateWith(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a SwitchStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitSwitchStatement(node) {
            return ts.updateSwitch(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.caseBlock, nestedElementVisitor, ts.isCaseBlock));
        }
        /**
         * Visits the body of a CaseBlock to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCaseBlock(node, ts.visitNodes(node.clauses, nestedElementVisitor, ts.isCaseOrDefaultClause));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a CaseClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseClause(node) {
            return ts.updateCaseClause(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNodes(node.statements, nestedElementVisitor, ts.isStatement));
        }
        /**
         * Visits the body of a DefaultClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDefaultClause(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a TryStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitTryStatement(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a CatchClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCatchClause(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCatchClause(node, node.variableDeclaration, ts.visitNode(node.block, nestedElementVisitor, ts.isBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a Block to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.visitEachChild(node, nestedElementVisitor, context);
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        //
        // Destructuring Assignment Visitors
        //
        /**
         * Visit nodes to flatten destructuring assignments to exported symbols.
         *
         * @param node The node to visit.
         */
        function destructuringAndImportCallVisitor(node) {
            if (node.transformFlags & 1024 /* DestructuringAssignment */
                && node.kind === 194 /* BinaryExpression */) {
                return visitDestructuringAssignment(node);
            }
            else if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if ((node.transformFlags & 2048 /* ContainsDestructuringAssignment */) || (node.transformFlags & 67108864 /* ContainsDynamicImport */)) {
                return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
            }
            else {
                return node;
            }
        }
        function visitImportCallExpression(node) {
            // import("./blah")
            // emit as
            // System.register([], function (_export, _context) {
            //     return {
            //         setters: [],
            //         execute: () => {
            //             _context.import('./blah');
            //         }
            //     };
            // });
            return ts.createCall(ts.createPropertyAccess(contextObject, ts.createIdentifier("import")), 
            /*typeArguments*/ undefined, ts.some(node.arguments) ? [ts.visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : []);
        }
        /**
         * Visits a DestructuringAssignment to flatten destructuring to exported symbols.
         *
         * @param node The node to visit.
         */
        function visitDestructuringAssignment(node) {
            if (hasExportedReferenceInDestructuringTarget(node.left)) {
                return ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ true);
            }
            return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
        }
        /**
         * Determines whether the target of a destructuring assigment refers to an exported symbol.
         *
         * @param node The destructuring target.
         */
        function hasExportedReferenceInDestructuringTarget(node) {
            if (ts.isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
                return hasExportedReferenceInDestructuringTarget(node.left);
            }
            else if (ts.isSpreadElement(node)) {
                return hasExportedReferenceInDestructuringTarget(node.expression);
            }
            else if (ts.isObjectLiteralExpression(node)) {
                return ts.some(node.properties, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isArrayLiteralExpression(node)) {
                return ts.some(node.elements, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.name);
            }
            else if (ts.isPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.initializer);
            }
            else if (ts.isIdentifier(node)) {
                var container = resolver.getReferencedExportContainer(node);
                return container !== undefined && container.kind === 265 /* SourceFile */;
            }
            else {
                return false;
            }
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            switch (node.kind) {
                case 84 /* ExportKeyword */:
                case 79 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 265 /* SourceFile */) {
                var id = ts.getOriginalNodeId(node);
                currentSourceFile = node;
                moduleInfo = moduleInfoMap[id];
                exportFunction = exportFunctionsMap[id];
                noSubstitution = noSubstitutionMap[id];
                if (noSubstitution) {
                    delete noSubstitutionMap[id];
                }
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                moduleInfo = undefined;
                exportFunction = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (isSubstitutionPrevented(node)) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        /**
         * Substitute the expression, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 194 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 192 /* PrefixUnaryExpression */:
                case 193 /* PostfixUnaryExpression */:
                    return substituteUnaryExpression(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            // When we see an identifier in an expression position that
            // points to an imported symbol, we should substitute a qualified
            // reference to the imported symbol if one is needed.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_3 = exportedNames; _i < exportedNames_3.length; _i++) {
                        var exportName = exportedNames_3[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 193 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createPrefix(node.operator, node.operand), node)
                        : node;
                    for (var _i = 0, exportedNames_4 = exportedNames; _i < exportedNames_4.length; _i++) {
                        var exportName = exportedNames_4[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    if (node.kind === 193 /* PostfixUnaryExpression */) {
                        expression = node.operator === 43 /* PlusPlusToken */
                            ? ts.createSubtract(preventSubstitution(expression), ts.createLiteral(1))
                            : ts.createAdd(preventSubstitution(expression), ts.createLiteral(1));
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Gets the exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            var exportedNames;
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    var exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false);
                    if (exportContainer && exportContainer.kind === 265 /* SourceFile */) {
                        exportedNames = ts.append(exportedNames, ts.getDeclarationName(valueDeclaration));
                    }
                    exportedNames = ts.addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]);
                }
            }
            return exportedNames;
        }
        /**
         * Prevent substitution of a node for this transformer.
         *
         * @param node The node which should not be substituted.
         */
        function preventSubstitution(node) {
            if (noSubstitution === undefined)
                noSubstitution = [];
            noSubstitution[ts.getNodeId(node)] = true;
            return node;
        }
        /**
         * Determines whether a node should not be substituted.
         *
         * @param node The node to test.
         */
        function isSubstitutionPrevented(node) {
            return noSubstitution && node.id && noSubstitution[node.id];
        }
    }
    ts.transformSystemModule = transformSystemModule;
})(ts || (ts = {}));
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/*@internal*/
var ts;
(function (ts) {
    function transformES2015Module(context) {
        var compilerOptions = context.getCompilerOptions();
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableEmitNotification(265 /* SourceFile */);
        context.enableSubstitution(71 /* Identifier */);
        var currentSourceFile;
        return transformSourceFile;
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
                var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
                if (externalHelpersModuleName) {
                    var statements = [];
                    var statementOffset = ts.addPrologue(statements, node.statements);
                    ts.append(statements, ts.createImportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText)));
                    ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
                    return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
                }
                else {
                    return ts.visitEachChild(node, visitor, context);
                }
            }
            return node;
        }
        function visitor(node) {
            switch (node.kind) {
                case 237 /* ImportEqualsDeclaration */:
                    // Elide `import=` as it is not legal with --module ES6
                    return undefined;
                case 243 /* ExportAssignment */:
                    return visitExportAssignment(node);
            }
            return node;
        }
        function visitExportAssignment(node) {
            // Elide `export=` as it is not legal with --module ES6
            return node.isExportEquals ? undefined : node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (ts.isSourceFile(node)) {
                currentSourceFile = node;
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (ts.isIdentifier(node) && hint === 1 /* Expression */) {
                return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
            }
            return node;
        }
    }
    ts.transformES2015Module = transformES2015Module;
})(ts || (ts = {}));
/// <reference path="visitor.ts" />
/// <reference path="transformers/utilities.ts" />
/// <reference path="transformers/ts.ts" />
/// <reference path="transformers/jsx.ts" />
/// <reference path="transformers/esnext.ts" />
/// <reference path="transformers/es2017.ts" />
/// <reference path="transformers/es2016.ts" />
/// <reference path="transformers/es2015.ts" />
/// <reference path="transformers/generators.ts" />
/// <reference path="transformers/es5.ts" />
/// <reference path="transformers/module/module.ts" />
/// <reference path="transformers/module/system.ts" />
/// <reference path="transformers/module/es2015.ts" />
/* @internal */
var ts;
(function (ts) {
    function getModuleTransformer(moduleKind) {
        switch (moduleKind) {
            case ts.ModuleKind.ESNext:
            case ts.ModuleKind.ES2015:
                return ts.transformES2015Module;
            case ts.ModuleKind.System:
                return ts.transformSystemModule;
            default:
                return ts.transformModule;
        }
    }
    var TransformationState;
    (function (TransformationState) {
        TransformationState[TransformationState["Uninitialized"] = 0] = "Uninitialized";
        TransformationState[TransformationState["Initialized"] = 1] = "Initialized";
        TransformationState[TransformationState["Completed"] = 2] = "Completed";
        TransformationState[TransformationState["Disposed"] = 3] = "Disposed";
    })(TransformationState || (TransformationState = {}));
    var SyntaxKindFeatureFlags;
    (function (SyntaxKindFeatureFlags) {
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["Substitution"] = 1] = "Substitution";
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["EmitNotifications"] = 2] = "EmitNotifications";
    })(SyntaxKindFeatureFlags || (SyntaxKindFeatureFlags = {}));
    function getTransformers(compilerOptions, customTransformers) {
        var jsx = compilerOptions.jsx;
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var transformers = [];
        ts.addRange(transformers, customTransformers && customTransformers.before);
        transformers.push(ts.transformTypeScript);
        if (jsx === 2 /* React */) {
            transformers.push(ts.transformJsx);
        }
        if (languageVersion < 5 /* ESNext */) {
            transformers.push(ts.transformESNext);
        }
        if (languageVersion < 4 /* ES2017 */) {
            transformers.push(ts.transformES2017);
        }
        if (languageVersion < 3 /* ES2016 */) {
            transformers.push(ts.transformES2016);
        }
        if (languageVersion < 2 /* ES2015 */) {
            transformers.push(ts.transformES2015);
            transformers.push(ts.transformGenerators);
        }
        transformers.push(getModuleTransformer(moduleKind));
        // The ES5 transformer is last so that it can substitute expressions like `exports.default`
        // for ES3.
        if (languageVersion < 1 /* ES5 */) {
            transformers.push(ts.transformES5);
        }
        ts.addRange(transformers, customTransformers && customTransformers.after);
        return transformers;
    }
    ts.getTransformers = getTransformers;
    /**
     * Transforms an array of SourceFiles by passing them through each transformer.
     *
     * @param resolver The emit resolver provided by the checker.
     * @param host The emit host object used to interact with the file system.
     * @param options Compiler options to surface in the `TransformationContext`.
     * @param nodes An array of nodes to transform.
     * @param transforms An array of `TransformerFactory` callbacks.
     * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
     */
    function transformNodes(resolver, host, options, nodes, transformers, allowDtsFiles) {
        var enabledSyntaxKindFeatures = new Array(292 /* Count */);
        var lexicalEnvironmentVariableDeclarations;
        var lexicalEnvironmentFunctionDeclarations;
        var lexicalEnvironmentVariableDeclarationsStack = [];
        var lexicalEnvironmentFunctionDeclarationsStack = [];
        var lexicalEnvironmentStackOffset = 0;
        var lexicalEnvironmentSuspended = false;
        var emitHelpers;
        var onSubstituteNode = function (_, node) { return node; };
        var onEmitNode = function (hint, node, callback) { return callback(hint, node); };
        var state = 0 /* Uninitialized */;
        // The transformation context is provided to each transformer as part of transformer
        // initialization.
        var context = {
            getCompilerOptions: function () { return options; },
            getEmitResolver: function () { return resolver; },
            getEmitHost: function () { return host; },
            startLexicalEnvironment: startLexicalEnvironment,
            suspendLexicalEnvironment: suspendLexicalEnvironment,
            resumeLexicalEnvironment: resumeLexicalEnvironment,
            endLexicalEnvironment: endLexicalEnvironment,
            hoistVariableDeclaration: hoistVariableDeclaration,
            hoistFunctionDeclaration: hoistFunctionDeclaration,
            requestEmitHelper: requestEmitHelper,
            readEmitHelpers: readEmitHelpers,
            enableSubstitution: enableSubstitution,
            enableEmitNotification: enableEmitNotification,
            isSubstitutionEnabled: isSubstitutionEnabled,
            isEmitNotificationEnabled: isEmitNotificationEnabled,
            get onSubstituteNode() { return onSubstituteNode; },
            set onSubstituteNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onSubstituteNode = value;
            },
            get onEmitNode() { return onEmitNode; },
            set onEmitNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onEmitNode = value;
            }
        };
        // Ensure the parse tree is clean before applying transformations
        for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) {
            var node = nodes_4[_i];
            ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
        }
        ts.performance.mark("beforeTransform");
        // Chain together and initialize each transformer.
        var transformation = ts.chain.apply(void 0, transformers)(context);
        // prevent modification of transformation hooks.
        state = 1 /* Initialized */;
        // Transform each node.
        var transformed = ts.map(nodes, allowDtsFiles ? transformation : transformRoot);
        // prevent modification of the lexical environment.
        state = 2 /* Completed */;
        ts.performance.mark("afterTransform");
        ts.performance.measure("transformTime", "beforeTransform", "afterTransform");
        return {
            transformed: transformed,
            substituteNode: substituteNode,
            emitNodeWithNotification: emitNodeWithNotification,
            dispose: dispose
        };
        function transformRoot(node) {
            return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node;
        }
        /**
         * Enables expression substitutions in the pretty printer for the provided SyntaxKind.
         */
        function enableSubstitution(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */;
        }
        /**
         * Determines whether expression substitutions are enabled for the provided node.
         */
        function isSubstitutionEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0
                && (ts.getEmitFlags(node) & 4 /* NoSubstitution */) === 0;
        }
        /**
         * Emits a node with possible substitution.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node or its substitute.
         */
        function substituteNode(hint, node) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed.");
            return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
        }
        /**
         * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
         */
        function enableEmitNotification(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */;
        }
        /**
         * Determines whether before/after emit notifications should be raised in the pretty
         * printer when it emits a node.
         */
        function isEmitNotificationEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0
                || (ts.getEmitFlags(node) & 2 /* AdviseOnEmitNode */) !== 0;
        }
        /**
         * Emits a node with possible emit notification.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node.
         */
        function emitNodeWithNotification(hint, node, emitCallback) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed.");
            if (node) {
                if (isEmitNotificationEnabled(node)) {
                    onEmitNode(hint, node, emitCallback);
                }
                else {
                    emitCallback(hint, node);
                }
            }
        }
        /**
         * Records a hoisted variable declaration for the provided name within a lexical environment.
         */
        function hoistVariableDeclaration(name) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            var decl = ts.setEmitFlags(ts.createVariableDeclaration(name), 64 /* NoNestedSourceMaps */);
            if (!lexicalEnvironmentVariableDeclarations) {
                lexicalEnvironmentVariableDeclarations = [decl];
            }
            else {
                lexicalEnvironmentVariableDeclarations.push(decl);
            }
        }
        /**
         * Records a hoisted function declaration within a lexical environment.
         */
        function hoistFunctionDeclaration(func) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            if (!lexicalEnvironmentFunctionDeclarations) {
                lexicalEnvironmentFunctionDeclarations = [func];
            }
            else {
                lexicalEnvironmentFunctionDeclarations.push(func);
            }
        }
        /**
         * Starts a new lexical environment. Any existing hoisted variable or function declarations
         * are pushed onto a stack, and the related storage variables are reset.
         */
        function startLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            // Save the current lexical environment. Rather than resizing the array we adjust the
            // stack size variable. This allows us to reuse existing array slots we've
            // already allocated between transformations to avoid allocation and GC overhead during
            // transformation.
            lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
            lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
            lexicalEnvironmentStackOffset++;
            lexicalEnvironmentVariableDeclarations = undefined;
            lexicalEnvironmentFunctionDeclarations = undefined;
        }
        /** Suspends the current lexical environment, usually after visiting a parameter list. */
        function suspendLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
            lexicalEnvironmentSuspended = true;
        }
        /** Resumes a suspended lexical environment, usually before visiting a function body. */
        function resumeLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
            lexicalEnvironmentSuspended = false;
        }
        /**
         * Ends a lexical environment. The previous set of hoisted declarations are restored and
         * any hoisted declarations added in this environment are returned.
         */
        function endLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            var statements;
            if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) {
                if (lexicalEnvironmentFunctionDeclarations) {
                    statements = lexicalEnvironmentFunctionDeclarations.slice();
                }
                if (lexicalEnvironmentVariableDeclarations) {
                    var statement = ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations));
                    if (!statements) {
                        statements = [statement];
                    }
                    else {
                        statements.push(statement);
                    }
                }
            }
            // Restore the previous lexical environment.
            lexicalEnvironmentStackOffset--;
            lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
            if (lexicalEnvironmentStackOffset === 0) {
                lexicalEnvironmentVariableDeclarationsStack = [];
                lexicalEnvironmentFunctionDeclarationsStack = [];
            }
            return statements;
        }
        function requestEmitHelper(helper) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
            emitHelpers = ts.append(emitHelpers, helper);
        }
        function readEmitHelpers() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            var helpers = emitHelpers;
            emitHelpers = undefined;
            return helpers;
        }
        function dispose() {
            if (state < 3 /* Disposed */) {
                // Clean up emit nodes on parse tree
                for (var _i = 0, nodes_5 = nodes; _i < nodes_5.length; _i++) {
                    var node = nodes_5[_i];
                    ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
                }
                // Release references to external entries for GC purposes.
                lexicalEnvironmentVariableDeclarations = undefined;
                lexicalEnvironmentVariableDeclarationsStack = undefined;
                lexicalEnvironmentFunctionDeclarations = undefined;
                lexicalEnvironmentFunctionDeclarationsStack = undefined;
                onSubstituteNode = undefined;
                onEmitNode = undefined;
                emitHelpers = undefined;
                // Prevent further use of the transformation result.
                state = 3 /* Disposed */;
            }
        }
    }
    ts.transformNodes = transformNodes;
})(ts || (ts = {}));
/// <reference path="checker.ts"/>
/* @internal */
var ts;
(function (ts) {
    // Used for initialize lastEncodedSourceMapSpan and reset lastEncodedSourceMapSpan when updateLastEncodedAndRecordedSpans
    var defaultLastEncodedSourceMapSpan = {
        emittedLine: 1,
        emittedColumn: 1,
        sourceLine: 1,
        sourceColumn: 1,
        sourceIndex: 0
    };
    function createSourceMapWriter(host, writer) {
        var compilerOptions = host.getCompilerOptions();
        var extendedDiagnostics = compilerOptions.extendedDiagnostics;
        var currentSource;
        var currentSourceText;
        var sourceMapDir; // The directory in which sourcemap will be
        // Current source map file and its index in the sources list
        var sourceMapSourceIndex;
        // Last recorded and encoded spans
        var lastRecordedSourceMapSpan;
        var lastEncodedSourceMapSpan;
        var lastEncodedNameIndex;
        // Source map data
        var sourceMapData;
        var disabled = !(compilerOptions.sourceMap || compilerOptions.inlineSourceMap);
        return {
            initialize: initialize,
            reset: reset,
            getSourceMapData: function () { return sourceMapData; },
            setSourceFile: setSourceFile,
            emitPos: emitPos,
            emitNodeWithSourceMap: emitNodeWithSourceMap,
            emitTokenWithSourceMap: emitTokenWithSourceMap,
            getText: getText,
            getSourceMappingURL: getSourceMappingURL,
        };
        /**
         * Skips trivia such as comments and white-space that can optionally overriden by the source map source
         */
        function skipSourceTrivia(pos) {
            return currentSource.skipTrivia ? currentSource.skipTrivia(pos) : ts.skipTrivia(currentSourceText, pos);
        }
        /**
         * Initialize the SourceMapWriter for a new output file.
         *
         * @param filePath The path to the generated output file.
         * @param sourceMapFilePath The path to the output source map file.
         * @param sourceFileOrBundle The input source file or bundle for the program.
         */
        function initialize(filePath, sourceMapFilePath, sourceFileOrBundle) {
            if (disabled) {
                return;
            }
            if (sourceMapData) {
                reset();
            }
            currentSource = undefined;
            currentSourceText = undefined;
            // Current source map file and its index in the sources list
            sourceMapSourceIndex = -1;
            // Last recorded and encoded spans
            lastRecordedSourceMapSpan = undefined;
            lastEncodedSourceMapSpan = defaultLastEncodedSourceMapSpan;
            lastEncodedNameIndex = 0;
            // Initialize source map data
            sourceMapData = {
                sourceMapFilePath: sourceMapFilePath,
                jsSourceMappingURL: !compilerOptions.inlineSourceMap ? ts.getBaseFileName(ts.normalizeSlashes(sourceMapFilePath)) : undefined,
                sourceMapFile: ts.getBaseFileName(ts.normalizeSlashes(filePath)),
                sourceMapSourceRoot: compilerOptions.sourceRoot || "",
                sourceMapSources: [],
                inputSourceFileNames: [],
                sourceMapNames: [],
                sourceMapMappings: "",
                sourceMapSourcesContent: compilerOptions.inlineSources ? [] : undefined,
                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 (sourceFileOrBundle.kind === 265 /* SourceFile */) {
                    // 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(sourceFileOrBundle, 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(filePath)), // get the relative sourceMapDir path based on jsFilePath
                    ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap
                    host.getCurrentDirectory(), host.getCanonicalFileName, 
                    /*isAbsolutePathAnUrl*/ true);
                }
                else {
                    sourceMapData.jsSourceMappingURL = ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL);
                }
            }
            else {
                sourceMapDir = ts.getDirectoryPath(ts.normalizePath(filePath));
            }
        }
        /**
         * Reset the SourceMapWriter to an empty state.
         */
        function reset() {
            if (disabled) {
                return;
            }
            currentSource = undefined;
            sourceMapDir = undefined;
            sourceMapSourceIndex = undefined;
            lastRecordedSourceMapSpan = undefined;
            lastEncodedSourceMapSpan = undefined;
            lastEncodedNameIndex = undefined;
            sourceMapData = undefined;
        }
        // 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) {
                ts.Debug.assert(false, "We do not support name index right now, Make sure to update updateLastEncodedAndRecordedSpans when we start using this");
                sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
                lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
            }
            lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
            sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
        }
        /**
         * Emits a mapping.
         *
         * If the position is synthetic (undefined or a negative value), no mapping will be
         * created.
         *
         * @param pos The position.
         */
        function emitPos(pos) {
            if (disabled || ts.positionIsSynthesized(pos)) {
                return;
            }
            if (extendedDiagnostics) {
                ts.performance.mark("beforeSourcemap");
            }
            var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSource, 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,
                    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;
            }
            if (extendedDiagnostics) {
                ts.performance.mark("afterSourcemap");
                ts.performance.measure("Source Map", "beforeSourcemap", "afterSourcemap");
            }
        }
        /**
         * Emits a node with possible leading and trailing source maps.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node.
         */
        function emitNodeWithSourceMap(hint, node, emitCallback) {
            if (disabled) {
                return emitCallback(hint, node);
            }
            if (node) {
                var emitNode = node.emitNode;
                var emitFlags = emitNode && emitNode.flags;
                var range = emitNode && emitNode.sourceMapRange;
                var _a = range || node, pos = _a.pos, end = _a.end;
                var source = range && range.source;
                var oldSource = currentSource;
                if (source === oldSource)
                    source = undefined;
                if (source)
                    setSourceFile(source);
                if (node.kind !== 287 /* NotEmittedStatement */
                    && (emitFlags & 16 /* NoLeadingSourceMap */) === 0
                    && pos >= 0) {
                    emitPos(skipSourceTrivia(pos));
                }
                if (source)
                    setSourceFile(oldSource);
                if (emitFlags & 64 /* NoNestedSourceMaps */) {
                    disabled = true;
                    emitCallback(hint, node);
                    disabled = false;
                }
                else {
                    emitCallback(hint, node);
                }
                if (source)
                    setSourceFile(source);
                if (node.kind !== 287 /* NotEmittedStatement */
                    && (emitFlags & 32 /* NoTrailingSourceMap */) === 0
                    && end >= 0) {
                    emitPos(end);
                }
                if (source)
                    setSourceFile(oldSource);
            }
        }
        /**
         * Emits a token of a node with possible leading and trailing source maps.
         *
         * @param node The node containing the token.
         * @param token The token to emit.
         * @param tokenStartPos The start pos of the token.
         * @param emitCallback The callback used to emit the token.
         */
        function emitTokenWithSourceMap(node, token, tokenPos, emitCallback) {
            if (disabled) {
                return emitCallback(token, tokenPos);
            }
            var emitNode = node && node.emitNode;
            var emitFlags = emitNode && emitNode.flags;
            var range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
            tokenPos = skipSourceTrivia(range ? range.pos : tokenPos);
            if ((emitFlags & 128 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) {
                emitPos(tokenPos);
            }
            tokenPos = emitCallback(token, tokenPos);
            if (range)
                tokenPos = range.end;
            if ((emitFlags & 256 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) {
                emitPos(tokenPos);
            }
            return tokenPos;
        }
        /**
         * Set the current source file.
         *
         * @param sourceFile The source file.
         */
        function setSourceFile(sourceFile) {
            if (disabled) {
                return;
            }
            currentSource = sourceFile;
            currentSourceText = currentSource.text;
            // 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;
            var source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, currentSource.fileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
            /*isAbsolutePathAnUrl*/ true);
            sourceMapSourceIndex = ts.indexOf(sourceMapData.sourceMapSources, source);
            if (sourceMapSourceIndex === -1) {
                sourceMapSourceIndex = sourceMapData.sourceMapSources.length;
                sourceMapData.sourceMapSources.push(source);
                // The one that can be used from program to get the actual source file
                sourceMapData.inputSourceFileNames.push(currentSource.fileName);
                if (compilerOptions.inlineSources) {
                    sourceMapData.sourceMapSourcesContent.push(currentSource.text);
                }
            }
        }
        /**
         * Gets the text for the source map.
         */
        function getText() {
            if (disabled) {
                return;
            }
            encodeLastRecordedSourceMapSpan();
            return JSON.stringify({
                version: 3,
                file: sourceMapData.sourceMapFile,
                sourceRoot: sourceMapData.sourceMapSourceRoot,
                sources: sourceMapData.sourceMapSources,
                names: sourceMapData.sourceMapNames,
                mappings: sourceMapData.sourceMapMappings,
                sourcesContent: sourceMapData.sourceMapSourcesContent,
            });
        }
        /**
         * Gets the SourceMappingURL for the source map.
         */
        function getSourceMappingURL() {
            if (disabled) {
                return;
            }
            if (compilerOptions.inlineSourceMap) {
                // Encode the sourceMap into the sourceMap url
                var base64SourceMapText = ts.convertToBase64(getText());
                return sourceMapData.jsSourceMappingURL = "data:application/json;base64," + base64SourceMapText;
            }
            else {
                return sourceMapData.jsSourceMappingURL;
            }
        }
    }
    ts.createSourceMapWriter = createSourceMapWriter;
    var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    function base64FormatEncode(inValue) {
        if (inValue < 64) {
            return base64Chars.charAt(inValue);
        }
        throw TypeError(inValue + ": not a 64 based value");
    }
    function base64VLQFormatEncode(inValue) {
        // 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;
    }
})(ts || (ts = {}));
/// <reference path="sourcemap.ts" />
/* @internal */
var ts;
(function (ts) {
    function createCommentWriter(printerOptions, emitPos) {
        var extendedDiagnostics = printerOptions.extendedDiagnostics;
        var newLine = ts.getNewLineCharacter(printerOptions);
        var writer;
        var containerPos = -1;
        var containerEnd = -1;
        var declarationListContainerEnd = -1;
        var currentSourceFile;
        var currentText;
        var currentLineMap;
        var detachedCommentsInfo;
        var hasWrittenComment = false;
        var disabled = printerOptions.removeComments;
        return {
            reset: reset,
            setWriter: setWriter,
            setSourceFile: setSourceFile,
            emitNodeWithComments: emitNodeWithComments,
            emitBodyWithDetachedComments: emitBodyWithDetachedComments,
            emitTrailingCommentsOfPosition: emitTrailingCommentsOfPosition,
            emitLeadingCommentsOfPosition: emitLeadingCommentsOfPosition,
        };
        function emitNodeWithComments(hint, node, emitCallback) {
            if (disabled) {
                emitCallback(hint, node);
                return;
            }
            if (node) {
                hasWrittenComment = false;
                var emitNode = node.emitNode;
                var emitFlags = emitNode && emitNode.flags;
                var _a = emitNode && emitNode.commentRange || node, pos = _a.pos, end = _a.end;
                if ((pos < 0 && end < 0) || (pos === end)) {
                    // Both pos and end are synthesized, so just emit the node without comments.
                    emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
                }
                else {
                    if (extendedDiagnostics) {
                        ts.performance.mark("preEmitNodeWithComment");
                    }
                    var isEmittedNode = node.kind !== 287 /* NotEmittedStatement */;
                    // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
                    // It is expensive to walk entire tree just to set one kind of node to have no comments.
                    var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0 || node.kind === 10 /* JsxText */;
                    var skipTrailingComments = end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0 || node.kind === 10 /* JsxText */;
                    // Emit leading comments if the position is not synthesized and the node
                    // has not opted out from emitting leading comments.
                    if (!skipLeadingComments) {
                        emitLeadingComments(pos, isEmittedNode);
                    }
                    // Save current container state on the stack.
                    var savedContainerPos = containerPos;
                    var savedContainerEnd = containerEnd;
                    var savedDeclarationListContainerEnd = declarationListContainerEnd;
                    if (!skipLeadingComments) {
                        containerPos = pos;
                    }
                    if (!skipTrailingComments) {
                        containerEnd = end;
                        // To avoid invalid comment emit in a down-level binding pattern, we
                        // keep track of the last declaration list container's end
                        if (node.kind === 227 /* VariableDeclarationList */) {
                            declarationListContainerEnd = end;
                        }
                    }
                    if (extendedDiagnostics) {
                        ts.performance.measure("commentTime", "preEmitNodeWithComment");
                    }
                    emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
                    if (extendedDiagnostics) {
                        ts.performance.mark("postEmitNodeWithComment");
                    }
                    // Restore previous container state.
                    containerPos = savedContainerPos;
                    containerEnd = savedContainerEnd;
                    declarationListContainerEnd = savedDeclarationListContainerEnd;
                    // Emit trailing comments if the position is not synthesized and the node
                    // has not opted out from emitting leading comments and is an emitted node.
                    if (!skipTrailingComments && isEmittedNode) {
                        emitTrailingComments(end);
                    }
                    if (extendedDiagnostics) {
                        ts.performance.measure("commentTime", "postEmitNodeWithComment");
                    }
                }
            }
        }
        function emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback) {
            var leadingComments = emitNode && emitNode.leadingComments;
            if (ts.some(leadingComments)) {
                if (extendedDiagnostics) {
                    ts.performance.mark("preEmitNodeWithSynthesizedComments");
                }
                ts.forEach(leadingComments, emitLeadingSynthesizedComment);
                if (extendedDiagnostics) {
                    ts.performance.measure("commentTime", "preEmitNodeWithSynthesizedComments");
                }
            }
            emitNodeWithNestedComments(hint, node, emitFlags, emitCallback);
            var trailingComments = emitNode && emitNode.trailingComments;
            if (ts.some(trailingComments)) {
                if (extendedDiagnostics) {
                    ts.performance.mark("postEmitNodeWithSynthesizedComments");
                }
                ts.forEach(trailingComments, emitTrailingSynthesizedComment);
                if (extendedDiagnostics) {
                    ts.performance.measure("commentTime", "postEmitNodeWithSynthesizedComments");
                }
            }
        }
        function emitLeadingSynthesizedComment(comment) {
            if (comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            else {
                writer.write(" ");
            }
        }
        function emitTrailingSynthesizedComment(comment) {
            if (!writer.isAtStartOfLine()) {
                writer.write(" ");
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function writeSynthesizedComment(comment) {
            var text = formatSynthesizedComment(comment);
            var lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? ts.computeLineStarts(text) : undefined;
            ts.writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
        }
        function formatSynthesizedComment(comment) {
            return comment.kind === 3 /* MultiLineCommentTrivia */
                ? "/*" + comment.text + "*/"
                : "//" + comment.text;
        }
        function emitNodeWithNestedComments(hint, node, emitFlags, emitCallback) {
            if (emitFlags & 2048 /* NoNestedComments */) {
                disabled = true;
                emitCallback(hint, node);
                disabled = false;
            }
            else {
                emitCallback(hint, node);
            }
        }
        function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
            if (extendedDiagnostics) {
                ts.performance.mark("preEmitBodyWithDetachedComments");
            }
            var pos = detachedRange.pos, end = detachedRange.end;
            var emitFlags = ts.getEmitFlags(node);
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0;
            var skipTrailingComments = disabled || end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0;
            if (!skipLeadingComments) {
                emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
            }
            if (extendedDiagnostics) {
                ts.performance.measure("commentTime", "preEmitBodyWithDetachedComments");
            }
            if (emitFlags & 2048 /* NoNestedComments */ && !disabled) {
                disabled = true;
                emitCallback(node);
                disabled = false;
            }
            else {
                emitCallback(node);
            }
            if (extendedDiagnostics) {
                ts.performance.mark("beginEmitBodyWithDetachedCommetns");
            }
            if (!skipTrailingComments) {
                emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
                if (hasWrittenComment && !writer.isAtStartOfLine()) {
                    writer.writeLine();
                }
            }
            if (extendedDiagnostics) {
                ts.performance.measure("commentTime", "beginEmitBodyWithDetachedCommetns");
            }
        }
        function emitLeadingComments(pos, isEmittedNode) {
            hasWrittenComment = false;
            if (isEmittedNode) {
                forEachLeadingCommentToEmit(pos, emitLeadingComment);
            }
            else if (pos === 0) {
                // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
                // unless it is a triple slash comment at the top of the file.
                // For Example:
                //      /// <reference-path ...>
                //      declare var x;
                //      /// <reference-path ...>
                //      interface F {}
                //  The first /// will NOT be removed while the second one will be removed even though both node will not be emitted
                forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
            }
        }
        function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (isTripleSlashComment(commentPos, commentEnd)) {
                emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
            }
        }
        function emitLeadingComment(commentPos, commentEnd, _kind, hasTrailingNewLine, rangePos) {
            if (!hasWrittenComment) {
                ts.emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
                hasWrittenComment = true;
            }
            // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
            if (emitPos)
                emitPos(commentPos);
            ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
            if (emitPos)
                emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else {
                writer.write(" ");
            }
        }
        function emitLeadingCommentsOfPosition(pos) {
            if (disabled || pos === -1) {
                return;
            }
            emitLeadingComments(pos, /*isEmittedNode*/ true);
        }
        function emitTrailingComments(pos) {
            forEachTrailingCommentToEmit(pos, emitTrailingComment);
        }
        function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
            if (!writer.isAtStartOfLine()) {
                writer.write(" ");
            }
            if (emitPos)
                emitPos(commentPos);
            ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
            if (emitPos)
                emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function emitTrailingCommentsOfPosition(pos, prefixSpace) {
            if (disabled) {
                return;
            }
            if (extendedDiagnostics) {
                ts.performance.mark("beforeEmitTrailingCommentsOfPosition");
            }
            forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
            if (extendedDiagnostics) {
                ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition");
            }
        }
        function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
            if (emitPos)
                emitPos(commentPos);
            ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
            if (emitPos)
                emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else {
                writer.write(" ");
            }
        }
        function forEachLeadingCommentToEmit(pos, cb) {
            // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
            if (containerPos === -1 || pos !== containerPos) {
                if (hasDetachedComments(pos)) {
                    forEachLeadingCommentWithoutDetachedComments(cb);
                }
                else {
                    ts.forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos);
                }
            }
        }
        function forEachTrailingCommentToEmit(end, cb) {
            // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
            if (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd)) {
                ts.forEachTrailingCommentRange(currentText, end, cb);
            }
        }
        function reset() {
            currentSourceFile = undefined;
            currentText = undefined;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
        }
        function setWriter(output) {
            writer = output;
        }
        function setSourceFile(sourceFile) {
            currentSourceFile = sourceFile;
            currentText = currentSourceFile.text;
            currentLineMap = ts.getLineStarts(currentSourceFile);
            detachedCommentsInfo = undefined;
        }
        function hasDetachedComments(pos) {
            return detachedCommentsInfo !== undefined && ts.lastOrUndefined(detachedCommentsInfo).nodePos === pos;
        }
        function forEachLeadingCommentWithoutDetachedComments(cb) {
            // get the leading comments from detachedPos
            var pos = ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos;
            if (detachedCommentsInfo.length - 1) {
                detachedCommentsInfo.pop();
            }
            else {
                detachedCommentsInfo = undefined;
            }
            ts.forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos);
        }
        function emitDetachedCommentsAndUpdateCommentsInfo(range) {
            var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, range, newLine, disabled);
            if (currentDetachedCommentInfo) {
                if (detachedCommentsInfo) {
                    detachedCommentsInfo.push(currentDetachedCommentInfo);
                }
                else {
                    detachedCommentsInfo = [currentDetachedCommentInfo];
                }
            }
        }
        function writeComment(text, lineMap, writer, commentPos, commentEnd, newLine) {
            if (emitPos)
                emitPos(commentPos);
            ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
            if (emitPos)
                emitPos(commentEnd);
        }
        /**
         * Determine if the given comment is a triple-slash
         *
         * @return true if the comment is a triple-slash comment else false
         */
        function isTripleSlashComment(commentPos, commentEnd) {
            return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd);
        }
    }
    ts.createCommentWriter = createCommentWriter;
})(ts || (ts = {}));
/// <reference path="checker.ts"/>
/* @internal */
var ts;
(function (ts) {
    function getDeclarationDiagnostics(host, resolver, targetSourceFile) {
        var declarationDiagnostics = ts.createDiagnosticCollection();
        ts.forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
        return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
        function getDeclarationDiagnosticsFromFile(_a, sourceFileOrBundle) {
            var declarationFilePath = _a.declarationFilePath;
            emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false);
        }
    }
    ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
    function emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles) {
        var sourceFiles = sourceFileOrBundle.kind === 266 /* Bundle */ ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
        var isBundledEmit = sourceFileOrBundle.kind === 266 /* Bundle */;
        var newLine = host.getNewLine();
        var compilerOptions = host.getCompilerOptions();
        var write;
        var writeLine;
        var increaseIndent;
        var decreaseIndent;
        var writeTextOfNode;
        var writer;
        createAndSetNewTextWriterWithSymbolWriter();
        var enclosingDeclaration;
        var resultHasExternalModuleIndicator;
        var currentText;
        var currentLineMap;
        var currentIdentifiers;
        var isCurrentFileExternalModule;
        var reportedDeclarationError = false;
        var errorNameNode;
        var emitJsDocComments = compilerOptions.removeComments ? ts.noop : writeJsDocComments;
        var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
        var needsDeclare = true;
        var moduleElementDeclarationEmitInfo = [];
        var asynchronousSubModuleDeclarationEmitInfo;
        // Contains the reference paths that needs to go in the declaration file.
        // Collecting this separately because reference paths need to be first thing in the declaration file
        // and we could be collecting these paths from multiple files into single one with --out option
        var referencesOutput = "";
        var usedTypeDirectiveReferences;
        // Emit references corresponding to each file
        var emittedReferencedFiles = [];
        var addedGlobalFileReference = false;
        var allSourcesModuleElementDeclarationEmitInfo = [];
        ts.forEach(sourceFiles, function (sourceFile) {
            // Dont emit for javascript file
            if (ts.isSourceFileJavaScript(sourceFile)) {
                return;
            }
            // Check what references need to be added
            if (!compilerOptions.noResolve) {
                ts.forEach(sourceFile.referencedFiles, function (fileReference) {
                    var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference);
                    // Emit reference in dts, if the file reference was not already emitted
                    if (referencedFile && !ts.contains(emittedReferencedFiles, referencedFile)) {
                        // Add a reference to generated dts file,
                        // global file reference is added only
                        //  - if it is not bundled emit (because otherwise it would be self reference)
                        //  - and it is not already added
                        if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference, emitOnlyDtsFiles)) {
                            addedGlobalFileReference = true;
                        }
                        emittedReferencedFiles.push(referencedFile);
                    }
                });
            }
            resultHasExternalModuleIndicator = false;
            if (!isBundledEmit || !ts.isExternalModule(sourceFile)) {
                needsDeclare = true;
                emitSourceFile(sourceFile);
            }
            else if (ts.isExternalModule(sourceFile)) {
                needsDeclare = false;
                write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {");
                writeLine();
                increaseIndent();
                emitSourceFile(sourceFile);
                decreaseIndent();
                write("}");
                writeLine();
            }
            // create asynchronous output for the importDeclarations
            if (moduleElementDeclarationEmitInfo.length) {
                var oldWriter = writer;
                ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
                    if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
                        ts.Debug.assert(aliasEmitInfo.node.kind === 238 /* ImportDeclaration */);
                        createAndSetNewTextWriterWithSymbolWriter();
                        ts.Debug.assert(aliasEmitInfo.indent === 0 || (aliasEmitInfo.indent === 1 && isBundledEmit));
                        for (var i = 0; i < aliasEmitInfo.indent; i++) {
                            increaseIndent();
                        }
                        writeImportDeclaration(aliasEmitInfo.node);
                        aliasEmitInfo.asynchronousOutput = writer.getText();
                        for (var i = 0; i < aliasEmitInfo.indent; i++) {
                            decreaseIndent();
                        }
                    }
                });
                setWriter(oldWriter);
                allSourcesModuleElementDeclarationEmitInfo = allSourcesModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
                moduleElementDeclarationEmitInfo = [];
            }
            if (!isBundledEmit && ts.isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
                // if file was external module with augmentations - this fact should be preserved in .d.ts as well.
                // in case if we didn't write any external module specifiers in .d.ts we need to emit something
                // that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
                write("export {};");
                writeLine();
            }
        });
        if (usedTypeDirectiveReferences) {
            ts.forEachKey(usedTypeDirectiveReferences, function (directive) {
                referencesOutput += "/// <reference types=\"" + directive + "\" />" + newLine;
            });
        }
        return {
            reportedDeclarationError: reportedDeclarationError,
            moduleElementDeclarationEmitInfo: allSourcesModuleElementDeclarationEmitInfo,
            synchronousDeclarationOutput: writer.getText(),
            referencesOutput: referencesOutput,
        };
        function hasInternalAnnotation(range) {
            var comment = currentText.substring(range.pos, range.end);
            return ts.stringContains(comment, "@internal");
        }
        function stripInternal(node) {
            if (node) {
                var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos);
                if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) {
                    return;
                }
                emitNode(node);
            }
        }
        function createAndSetNewTextWriterWithSymbolWriter() {
            var writer = ts.createTextWriter(newLine);
            writer.trackSymbol = trackSymbol;
            writer.reportInaccessibleThisError = reportInaccessibleThisError;
            writer.reportPrivateInBaseOfClassExpression = reportPrivateInBaseOfClassExpression;
            writer.writeKeyword = writer.write;
            writer.writeOperator = writer.write;
            writer.writePunctuation = writer.write;
            writer.writeSpace = writer.write;
            writer.writeStringLiteral = writer.writeLiteral;
            writer.writeParameter = writer.write;
            writer.writeProperty = writer.write;
            writer.writeSymbol = writer.write;
            setWriter(writer);
        }
        function setWriter(newWriter) {
            writer = newWriter;
            write = newWriter.write;
            writeTextOfNode = newWriter.writeTextOfNode;
            writeLine = newWriter.writeLine;
            increaseIndent = newWriter.increaseIndent;
            decreaseIndent = newWriter.decreaseIndent;
        }
        function writeAsynchronousModuleElements(nodes) {
            var oldWriter = writer;
            ts.forEach(nodes, function (declaration) {
                var nodeToCheck;
                if (declaration.kind === 226 /* VariableDeclaration */) {
                    nodeToCheck = declaration.parent.parent;
                }
                else if (declaration.kind === 241 /* NamedImports */ || declaration.kind === 242 /* ImportSpecifier */ || declaration.kind === 239 /* ImportClause */) {
                    ts.Debug.fail("We should be getting ImportDeclaration instead to write");
                }
                else {
                    nodeToCheck = declaration;
                }
                var moduleElementEmitInfo = ts.forEach(moduleElementDeclarationEmitInfo, function (declEmitInfo) { return declEmitInfo.node === nodeToCheck ? declEmitInfo : undefined; });
                if (!moduleElementEmitInfo && asynchronousSubModuleDeclarationEmitInfo) {
                    moduleElementEmitInfo = ts.forEach(asynchronousSubModuleDeclarationEmitInfo, function (declEmitInfo) { return declEmitInfo.node === nodeToCheck ? declEmitInfo : undefined; });
                }
                // If the alias was marked as not visible when we saw its declaration, we would have saved the aliasEmitInfo, but if we haven't yet visited the alias declaration
                // then we don't need to write it at this point. We will write it when we actually see its declaration
                // Eg.
                // export function bar(a: foo.Foo) { }
                // import foo = require("foo");
                // Writing of function bar would mark alias declaration foo as visible but we haven't yet visited that declaration so do nothing,
                // we would write alias foo declaration when we visit it since it would now be marked as visible
                if (moduleElementEmitInfo) {
                    if (moduleElementEmitInfo.node.kind === 238 /* ImportDeclaration */) {
                        // we have to create asynchronous output only after we have collected complete information
                        // because it is possible to enable multiple bindings as asynchronously visible
                        moduleElementEmitInfo.isVisible = true;
                    }
                    else {
                        createAndSetNewTextWriterWithSymbolWriter();
                        for (var declarationIndent = moduleElementEmitInfo.indent; declarationIndent; declarationIndent--) {
                            increaseIndent();
                        }
                        if (nodeToCheck.kind === 233 /* ModuleDeclaration */) {
                            ts.Debug.assert(asynchronousSubModuleDeclarationEmitInfo === undefined);
                            asynchronousSubModuleDeclarationEmitInfo = [];
                        }
                        writeModuleElement(nodeToCheck);
                        if (nodeToCheck.kind === 233 /* ModuleDeclaration */) {
                            moduleElementEmitInfo.subModuleElementDeclarationEmitInfo = asynchronousSubModuleDeclarationEmitInfo;
                            asynchronousSubModuleDeclarationEmitInfo = undefined;
                        }
                        moduleElementEmitInfo.asynchronousOutput = writer.getText();
                    }
                }
            });
            setWriter(oldWriter);
        }
        function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) {
            if (!typeReferenceDirectives) {
                return;
            }
            if (!usedTypeDirectiveReferences) {
                usedTypeDirectiveReferences = ts.createMap();
            }
            for (var _i = 0, typeReferenceDirectives_1 = typeReferenceDirectives; _i < typeReferenceDirectives_1.length; _i++) {
                var directive = typeReferenceDirectives_1[_i];
                if (!usedTypeDirectiveReferences.has(directive)) {
                    usedTypeDirectiveReferences.set(directive, directive);
                }
            }
        }
        function handleSymbolAccessibilityError(symbolAccessibilityResult) {
            if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) {
                // write the aliases
                if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) {
                    writeAsynchronousModuleElements(symbolAccessibilityResult.aliasesToMakeVisible);
                }
            }
            else {
                // Report error
                reportedDeclarationError = true;
                var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
                if (errorInfo) {
                    if (errorInfo.typeName) {
                        emitterDiagnostics.add(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                    else {
                        emitterDiagnostics.add(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                }
            }
        }
        function trackSymbol(symbol, enclosingDeclaration, meaning) {
            handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
        }
        function reportPrivateInBaseOfClassExpression(propertyName) {
            if (errorNameNode) {
                reportedDeclarationError = true;
                emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
            }
        }
        function reportInaccessibleThisError() {
            if (errorNameNode) {
                reportedDeclarationError = true;
                emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode)));
            }
        }
        function writeTypeOfDeclaration(declaration, type, getSymbolAccessibilityDiagnostic) {
            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
            write(": ");
            // use the checker's type, not the declared type,
            // for optional parameter properties
            // and also for non-optional initialized parameters that aren't a parameter property
            // these types may need to add `undefined`.
            var shouldUseResolverType = declaration.kind === 146 /* Parameter */ &&
                (resolver.isRequiredInitializedParameter(declaration) ||
                    resolver.isOptionalUninitializedParameterProperty(declaration));
            if (type && !shouldUseResolverType) {
                // Write the type
                emitType(type);
            }
            else {
                errorNameNode = declaration.name;
                var format = 4 /* UseTypeOfFunction */ |
                    16384 /* WriteClassExpressionAsTypeLiteral */ |
                    (shouldUseResolverType ? 8192 /* AddUndefined */ : 0);
                resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
                errorNameNode = undefined;
            }
        }
        function writeReturnTypeAtSignature(signature, getSymbolAccessibilityDiagnostic) {
            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
            write(": ");
            if (signature.type) {
                // Write the type
                emitType(signature.type);
            }
            else {
                errorNameNode = signature.name;
                resolver.writeReturnTypeOfSignatureDeclaration(signature, enclosingDeclaration, 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */, writer);
                errorNameNode = undefined;
            }
        }
        function emitLines(nodes) {
            for (var _i = 0, nodes_6 = nodes; _i < nodes_6.length; _i++) {
                var node = nodes_6[_i];
                emit(node);
            }
        }
        function emitSeparatedList(nodes, separator, eachNodeEmitFn, canEmitFn) {
            var currentWriterPos = writer.getTextPos();
            for (var _i = 0, nodes_7 = nodes; _i < nodes_7.length; _i++) {
                var node = nodes_7[_i];
                if (!canEmitFn || canEmitFn(node)) {
                    if (currentWriterPos !== writer.getTextPos()) {
                        write(separator);
                    }
                    currentWriterPos = writer.getTextPos();
                    eachNodeEmitFn(node);
                }
            }
        }
        function emitCommaList(nodes, eachNodeEmitFn, canEmitFn) {
            emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn);
        }
        function writeJsDocComments(declaration) {
            if (declaration) {
                var jsDocComments = ts.getJSDocCommentRanges(declaration, currentText);
                ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
                // jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
                ts.emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
            }
        }
        function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
            emitType(type);
        }
        function emitType(type) {
            switch (type.kind) {
                case 119 /* AnyKeyword */:
                case 136 /* StringKeyword */:
                case 133 /* NumberKeyword */:
                case 122 /* BooleanKeyword */:
                case 134 /* ObjectKeyword */:
                case 137 /* SymbolKeyword */:
                case 105 /* VoidKeyword */:
                case 139 /* UndefinedKeyword */:
                case 95 /* NullKeyword */:
                case 130 /* NeverKeyword */:
                case 169 /* ThisType */:
                case 173 /* LiteralType */:
                    return writeTextOfNode(currentText, type);
                case 201 /* ExpressionWithTypeArguments */:
                    return emitExpressionWithTypeArguments(type);
                case 159 /* TypeReference */:
                    return emitTypeReference(type);
                case 162 /* TypeQuery */:
                    return emitTypeQuery(type);
                case 164 /* ArrayType */:
                    return emitArrayType(type);
                case 165 /* TupleType */:
                    return emitTupleType(type);
                case 166 /* UnionType */:
                    return emitUnionType(type);
                case 167 /* IntersectionType */:
                    return emitIntersectionType(type);
                case 168 /* ParenthesizedType */:
                    return emitParenType(type);
                case 170 /* TypeOperator */:
                    return emitTypeOperator(type);
                case 171 /* IndexedAccessType */:
                    return emitIndexedAccessType(type);
                case 172 /* MappedType */:
                    return emitMappedType(type);
                case 160 /* FunctionType */:
                case 161 /* ConstructorType */:
                    return emitSignatureDeclarationWithJsDocComments(type);
                case 163 /* TypeLiteral */:
                    return emitTypeLiteral(type);
                case 71 /* Identifier */:
                    return emitEntityName(type);
                case 143 /* QualifiedName */:
                    return emitEntityName(type);
                case 158 /* TypePredicate */:
                    return emitTypePredicate(type);
            }
            function writeEntityName(entityName) {
                if (entityName.kind === 71 /* Identifier */) {
                    writeTextOfNode(currentText, entityName);
                }
                else {
                    var left = entityName.kind === 143 /* QualifiedName */ ? entityName.left : entityName.expression;
                    var right = entityName.kind === 143 /* QualifiedName */ ? entityName.right : entityName.name;
                    writeEntityName(left);
                    write(".");
                    writeTextOfNode(currentText, right);
                }
            }
            function emitEntityName(entityName) {
                var visibilityResult = resolver.isEntityNameVisible(entityName, 
                // Aliases can be written asynchronously so use correct enclosing declaration
                entityName.parent.kind === 237 /* ImportEqualsDeclaration */ ? entityName.parent : enclosingDeclaration);
                handleSymbolAccessibilityError(visibilityResult);
                recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
                writeEntityName(entityName);
            }
            function emitExpressionWithTypeArguments(node) {
                if (ts.isEntityNameExpression(node.expression)) {
                    ts.Debug.assert(node.expression.kind === 71 /* Identifier */ || node.expression.kind === 179 /* PropertyAccessExpression */);
                    emitEntityName(node.expression);
                    if (node.typeArguments) {
                        write("<");
                        emitCommaList(node.typeArguments, emitType);
                        write(">");
                    }
                }
            }
            function emitTypeReference(type) {
                emitEntityName(type.typeName);
                if (type.typeArguments) {
                    write("<");
                    emitCommaList(type.typeArguments, emitType);
                    write(">");
                }
            }
            function emitTypePredicate(type) {
                writeTextOfNode(currentText, type.parameterName);
                write(" is ");
                emitType(type.type);
            }
            function emitTypeQuery(type) {
                write("typeof ");
                emitEntityName(type.exprName);
            }
            function emitArrayType(type) {
                emitType(type.elementType);
                write("[]");
            }
            function emitTupleType(type) {
                write("[");
                emitCommaList(type.elementTypes, emitType);
                write("]");
            }
            function emitUnionType(type) {
                emitSeparatedList(type.types, " | ", emitType);
            }
            function emitIntersectionType(type) {
                emitSeparatedList(type.types, " & ", emitType);
            }
            function emitParenType(type) {
                write("(");
                emitType(type.type);
                write(")");
            }
            function emitTypeOperator(type) {
                write(ts.tokenToString(type.operator));
                write(" ");
                emitType(type.type);
            }
            function emitIndexedAccessType(node) {
                emitType(node.objectType);
                write("[");
                emitType(node.indexType);
                write("]");
            }
            function emitMappedType(node) {
                var prevEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = node;
                write("{");
                writeLine();
                increaseIndent();
                if (node.readonlyToken) {
                    write("readonly ");
                }
                write("[");
                writeEntityName(node.typeParameter.name);
                write(" in ");
                emitType(node.typeParameter.constraint);
                write("]");
                if (node.questionToken) {
                    write("?");
                }
                write(": ");
                emitType(node.type);
                write(";");
                writeLine();
                decreaseIndent();
                write("}");
                enclosingDeclaration = prevEnclosingDeclaration;
            }
            function emitTypeLiteral(type) {
                write("{");
                if (type.members.length) {
                    writeLine();
                    increaseIndent();
                    // write members
                    emitLines(type.members);
                    decreaseIndent();
                }
                write("}");
            }
        }
        function emitSourceFile(node) {
            currentText = node.text;
            currentLineMap = ts.getLineStarts(node);
            currentIdentifiers = node.identifiers;
            isCurrentFileExternalModule = ts.isExternalModule(node);
            enclosingDeclaration = node;
            ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, /*removeComments*/ true);
            emitLines(node.statements);
        }
        // Return a temp variable name to be used in `export default`/`export class ... extends` statements.
        // The temp name will be of the form _default_counter.
        // Note that export default is only allowed at most once in a module, so we
        // do not need to keep track of created temp names.
        function getExportTempVariableName(baseName) {
            if (!currentIdentifiers.has(baseName)) {
                return baseName;
            }
            var count = 0;
            while (true) {
                count++;
                var name = baseName + "_" + count;
                if (!currentIdentifiers.has(name)) {
                    return name;
                }
            }
        }
        function emitTempVariableDeclaration(expr, baseName, diagnostic, needsDeclare) {
            var tempVarName = getExportTempVariableName(baseName);
            if (needsDeclare) {
                write("declare ");
            }
            write("const ");
            write(tempVarName);
            write(": ");
            writer.getSymbolAccessibilityDiagnostic = function () { return diagnostic; };
            resolver.writeTypeOfExpression(expr, enclosingDeclaration, 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */, writer);
            write(";");
            writeLine();
            return tempVarName;
        }
        function emitExportAssignment(node) {
            if (node.expression.kind === 71 /* Identifier */) {
                write(node.isExportEquals ? "export = " : "export default ");
                writeTextOfNode(currentText, node.expression);
            }
            else {
                var tempVarName = emitTempVariableDeclaration(node.expression, "_default", {
                    diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
                    errorNode: node
                }, needsDeclare);
                write(node.isExportEquals ? "export = " : "export default ");
                write(tempVarName);
            }
            write(";");
            writeLine();
            // Make all the declarations visible for the export name
            if (node.expression.kind === 71 /* Identifier */) {
                var nodes = resolver.collectLinkedAliases(node.expression);
                // write each of these declarations asynchronously
                writeAsynchronousModuleElements(nodes);
            }
        }
        function isModuleElementVisible(node) {
            return resolver.isDeclarationVisible(node);
        }
        function emitModuleElement(node, isModuleElementVisible) {
            if (isModuleElementVisible) {
                writeModuleElement(node);
            }
            else if (node.kind === 237 /* ImportEqualsDeclaration */ ||
                (node.parent.kind === 265 /* SourceFile */ && isCurrentFileExternalModule)) {
                var isVisible = void 0;
                if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 265 /* SourceFile */) {
                    // Import declaration of another module that is visited async so lets put it in right spot
                    asynchronousSubModuleDeclarationEmitInfo.push({
                        node: node,
                        outputPos: writer.getTextPos(),
                        indent: writer.getIndent(),
                        isVisible: isVisible
                    });
                }
                else {
                    if (node.kind === 238 /* ImportDeclaration */) {
                        var importDeclaration = node;
                        if (importDeclaration.importClause) {
                            isVisible = (importDeclaration.importClause.name && resolver.isDeclarationVisible(importDeclaration.importClause)) ||
                                isVisibleNamedBinding(importDeclaration.importClause.namedBindings);
                        }
                    }
                    moduleElementDeclarationEmitInfo.push({
                        node: node,
                        outputPos: writer.getTextPos(),
                        indent: writer.getIndent(),
                        isVisible: isVisible
                    });
                }
            }
        }
        function writeModuleElement(node) {
            switch (node.kind) {
                case 228 /* FunctionDeclaration */:
                    return writeFunctionDeclaration(node);
                case 208 /* VariableStatement */:
                    return writeVariableStatement(node);
                case 230 /* InterfaceDeclaration */:
                    return writeInterfaceDeclaration(node);
                case 229 /* ClassDeclaration */:
                    return writeClassDeclaration(node);
                case 231 /* TypeAliasDeclaration */:
                    return writeTypeAliasDeclaration(node);
                case 232 /* EnumDeclaration */:
                    return writeEnumDeclaration(node);
                case 233 /* ModuleDeclaration */:
                    return writeModuleDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    return writeImportEqualsDeclaration(node);
                case 238 /* ImportDeclaration */:
                    return writeImportDeclaration(node);
                default:
                    ts.Debug.fail("Unknown symbol kind");
            }
        }
        function emitModuleElementDeclarationFlags(node) {
            // If the node is parented in the current source file we need to emit export declare or just export
            if (node.parent.kind === 265 /* SourceFile */) {
                var modifiers = ts.getModifierFlags(node);
                // If the node is exported
                if (modifiers & 1 /* Export */) {
                    write("export ");
                }
                if (modifiers & 512 /* Default */) {
                    write("default ");
                }
                else if (node.kind !== 230 /* InterfaceDeclaration */ && needsDeclare) {
                    write("declare ");
                }
            }
        }
        function emitClassMemberDeclarationFlags(flags) {
            if (flags & 8 /* Private */) {
                write("private ");
            }
            else if (flags & 16 /* Protected */) {
                write("protected ");
            }
            if (flags & 32 /* Static */) {
                write("static ");
            }
            if (flags & 64 /* Readonly */) {
                write("readonly ");
            }
            if (flags & 128 /* Abstract */) {
                write("abstract ");
            }
        }
        function writeImportEqualsDeclaration(node) {
            // note usage of writer. methods instead of aliases created, just to make sure we are using
            // correct writer especially to handle asynchronous alias writing
            emitJsDocComments(node);
            if (ts.hasModifier(node, 1 /* Export */)) {
                write("export ");
            }
            write("import ");
            writeTextOfNode(currentText, node.name);
            write(" = ");
            if (ts.isInternalModuleImportEqualsDeclaration(node)) {
                emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError);
                write(";");
            }
            else {
                write("require(");
                emitExternalModuleSpecifier(node);
                write(");");
            }
            writer.writeLine();
            function getImportEntityNameVisibilityError() {
                return {
                    diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1,
                    errorNode: node,
                    typeName: node.name
                };
            }
        }
        function isVisibleNamedBinding(namedBindings) {
            if (namedBindings) {
                if (namedBindings.kind === 240 /* NamespaceImport */) {
                    return resolver.isDeclarationVisible(namedBindings);
                }
                else {
                    return ts.forEach(namedBindings.elements, function (namedImport) { return resolver.isDeclarationVisible(namedImport); });
                }
            }
        }
        function writeImportDeclaration(node) {
            emitJsDocComments(node);
            if (ts.hasModifier(node, 1 /* Export */)) {
                write("export ");
            }
            write("import ");
            if (node.importClause) {
                var currentWriterPos = writer.getTextPos();
                if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
                    writeTextOfNode(currentText, node.importClause.name);
                }
                if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
                    if (currentWriterPos !== writer.getTextPos()) {
                        // If the default binding was emitted, write the separated
                        write(", ");
                    }
                    if (node.importClause.namedBindings.kind === 240 /* NamespaceImport */) {
                        write("* as ");
                        writeTextOfNode(currentText, node.importClause.namedBindings.name);
                    }
                    else {
                        write("{ ");
                        emitCommaList(node.importClause.namedBindings.elements, emitImportOrExportSpecifier, resolver.isDeclarationVisible);
                        write(" }");
                    }
                }
                write(" from ");
            }
            emitExternalModuleSpecifier(node);
            write(";");
            writer.writeLine();
        }
        function emitExternalModuleSpecifier(parent) {
            // emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
            // the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
            // external modules since they are indistinguishable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
            // so compiler will treat them as external modules.
            resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== 233 /* ModuleDeclaration */;
            var moduleSpecifier;
            if (parent.kind === 237 /* ImportEqualsDeclaration */) {
                var node = parent;
                moduleSpecifier = ts.getExternalModuleImportEqualsDeclarationExpression(node);
            }
            else if (parent.kind === 233 /* ModuleDeclaration */) {
                moduleSpecifier = parent.name;
            }
            else {
                var node = parent;
                moduleSpecifier = node.moduleSpecifier;
            }
            if (moduleSpecifier.kind === 9 /* StringLiteral */ && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
                var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, parent);
                if (moduleName) {
                    write('"');
                    write(moduleName);
                    write('"');
                    return;
                }
            }
            writeTextOfNode(currentText, moduleSpecifier);
        }
        function emitImportOrExportSpecifier(node) {
            if (node.propertyName) {
                writeTextOfNode(currentText, node.propertyName);
                write(" as ");
            }
            writeTextOfNode(currentText, node.name);
        }
        function emitExportSpecifier(node) {
            emitImportOrExportSpecifier(node);
            // Make all the declarations visible for the export name
            var nodes = resolver.collectLinkedAliases(node.propertyName || node.name);
            // write each of these declarations asynchronously
            writeAsynchronousModuleElements(nodes);
        }
        function emitExportDeclaration(node) {
            emitJsDocComments(node);
            write("export ");
            if (node.exportClause) {
                write("{ ");
                emitCommaList(node.exportClause.elements, emitExportSpecifier);
                write(" }");
            }
            else {
                write("*");
            }
            if (node.moduleSpecifier) {
                write(" from ");
                emitExternalModuleSpecifier(node);
            }
            write(";");
            writer.writeLine();
        }
        function writeModuleDeclaration(node) {
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            if (ts.isGlobalScopeAugmentation(node)) {
                write("global ");
            }
            else {
                if (node.flags & 16 /* Namespace */) {
                    write("namespace ");
                }
                else {
                    write("module ");
                }
                if (ts.isExternalModuleAugmentation(node)) {
                    emitExternalModuleSpecifier(node);
                }
                else {
                    writeTextOfNode(currentText, node.name);
                }
            }
            while (node.body && node.body.kind !== 234 /* ModuleBlock */) {
                node = node.body;
                write(".");
                writeTextOfNode(currentText, node.name);
            }
            var prevEnclosingDeclaration = enclosingDeclaration;
            if (node.body) {
                enclosingDeclaration = node;
                write(" {");
                writeLine();
                increaseIndent();
                emitLines(node.body.statements);
                decreaseIndent();
                write("}");
                writeLine();
                enclosingDeclaration = prevEnclosingDeclaration;
            }
            else {
                write(";");
            }
        }
        function writeTypeAliasDeclaration(node) {
            var prevEnclosingDeclaration = enclosingDeclaration;
            enclosingDeclaration = node;
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            write("type ");
            writeTextOfNode(currentText, node.name);
            emitTypeParameters(node.typeParameters);
            write(" = ");
            emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
            write(";");
            writeLine();
            enclosingDeclaration = prevEnclosingDeclaration;
            function getTypeAliasDeclarationVisibilityError() {
                return {
                    diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
                    errorNode: node.type,
                    typeName: node.name
                };
            }
        }
        function writeEnumDeclaration(node) {
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            if (ts.isConst(node)) {
                write("const ");
            }
            write("enum ");
            writeTextOfNode(currentText, node.name);
            write(" {");
            writeLine();
            increaseIndent();
            emitLines(node.members);
            decreaseIndent();
            write("}");
            writeLine();
        }
        function emitEnumMemberDeclaration(node) {
            emitJsDocComments(node);
            writeTextOfNode(currentText, node.name);
            var enumMemberValue = resolver.getConstantValue(node);
            if (enumMemberValue !== undefined) {
                write(" = ");
                write(ts.getTextOfConstantValue(enumMemberValue));
            }
            write(",");
            writeLine();
        }
        function isPrivateMethodTypeParameter(node) {
            return node.parent.kind === 151 /* MethodDeclaration */ && ts.hasModifier(node.parent, 8 /* Private */);
        }
        function emitTypeParameters(typeParameters) {
            function emitTypeParameter(node) {
                increaseIndent();
                emitJsDocComments(node);
                decreaseIndent();
                writeTextOfNode(currentText, node.name);
                // If there is constraint present and this is not a type parameter of the private method emit the constraint
                if (node.constraint && !isPrivateMethodTypeParameter(node)) {
                    write(" extends ");
                    if (node.parent.kind === 160 /* FunctionType */ ||
                        node.parent.kind === 161 /* ConstructorType */ ||
                        (node.parent.parent && node.parent.parent.kind === 163 /* TypeLiteral */)) {
                        ts.Debug.assert(node.parent.kind === 151 /* MethodDeclaration */ ||
                            node.parent.kind === 150 /* MethodSignature */ ||
                            node.parent.kind === 160 /* FunctionType */ ||
                            node.parent.kind === 161 /* ConstructorType */ ||
                            node.parent.kind === 155 /* CallSignature */ ||
                            node.parent.kind === 156 /* ConstructSignature */);
                        emitType(node.constraint);
                    }
                    else {
                        emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError);
                    }
                }
                if (node.default && !isPrivateMethodTypeParameter(node)) {
                    write(" = ");
                    if (node.parent.kind === 160 /* FunctionType */ ||
                        node.parent.kind === 161 /* ConstructorType */ ||
                        (node.parent.parent && node.parent.parent.kind === 163 /* TypeLiteral */)) {
                        ts.Debug.assert(node.parent.kind === 151 /* MethodDeclaration */ ||
                            node.parent.kind === 150 /* MethodSignature */ ||
                            node.parent.kind === 160 /* FunctionType */ ||
                            node.parent.kind === 161 /* ConstructorType */ ||
                            node.parent.kind === 155 /* CallSignature */ ||
                            node.parent.kind === 156 /* ConstructSignature */);
                        emitType(node.default);
                    }
                    else {
                        emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.default, getTypeParameterConstraintVisibilityError);
                    }
                }
                function getTypeParameterConstraintVisibilityError() {
                    // Type parameter constraints are named by user so we should always be able to name it
                    var diagnosticMessage;
                    switch (node.parent.kind) {
                        case 229 /* ClassDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
                            break;
                        case 230 /* InterfaceDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
                            break;
                        case 156 /* ConstructSignature */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                            break;
                        case 155 /* CallSignature */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                            break;
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                            if (ts.hasModifier(node.parent, 32 /* Static */)) {
                                diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                            }
                            else if (node.parent.parent.kind === 229 /* ClassDeclaration */) {
                                diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                            }
                            else {
                                diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                            }
                            break;
                        case 228 /* FunctionDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
                            break;
                        case 231 /* TypeAliasDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
                            break;
                        default:
                            ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
                    }
                    return {
                        diagnosticMessage: diagnosticMessage,
                        errorNode: node,
                        typeName: node.name
                    };
                }
            }
            if (typeParameters) {
                write("<");
                emitCommaList(typeParameters, emitTypeParameter);
                write(">");
            }
        }
        function emitHeritageClause(typeReferences, isImplementsList) {
            if (typeReferences) {
                write(isImplementsList ? " implements " : " extends ");
                emitCommaList(typeReferences, emitTypeOfTypeReference);
            }
            function emitTypeOfTypeReference(node) {
                if (ts.isEntityNameExpression(node.expression)) {
                    emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
                }
                else if (!isImplementsList && node.expression.kind === 95 /* NullKeyword */) {
                    write("null");
                }
                function getHeritageClauseVisibilityError() {
                    var diagnosticMessage;
                    // Heritage clause is written by user so it can always be named
                    if (node.parent.parent.kind === 229 /* ClassDeclaration */) {
                        // Class or Interface implemented/extended is inaccessible
                        diagnosticMessage = isImplementsList ?
                            ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
                            ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
                    }
                    else {
                        // interface is inaccessible
                        diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
                    }
                    return {
                        diagnosticMessage: diagnosticMessage,
                        errorNode: node,
                        typeName: ts.getNameOfDeclaration(node.parent.parent)
                    };
                }
            }
        }
        function writeClassDeclaration(node) {
            function emitParameterProperties(constructorDeclaration) {
                if (constructorDeclaration) {
                    ts.forEach(constructorDeclaration.parameters, function (param) {
                        if (ts.hasModifier(param, 92 /* ParameterPropertyModifier */)) {
                            emitPropertyDeclaration(param);
                        }
                    });
                }
            }
            var prevEnclosingDeclaration = enclosingDeclaration;
            enclosingDeclaration = node;
            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
            var tempVarName;
            if (baseTypeNode && !ts.isEntityNameExpression(baseTypeNode.expression)) {
                tempVarName = baseTypeNode.expression.kind === 95 /* NullKeyword */ ?
                    "null" :
                    emitTempVariableDeclaration(baseTypeNode.expression, node.name.escapedText + "_base", {
                        diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
                        errorNode: baseTypeNode,
                        typeName: node.name
                    }, !ts.findAncestor(node, function (n) { return n.kind === 233 /* ModuleDeclaration */; }));
            }
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            if (ts.hasModifier(node, 128 /* Abstract */)) {
                write("abstract ");
            }
            write("class ");
            writeTextOfNode(currentText, node.name);
            emitTypeParameters(node.typeParameters);
            if (baseTypeNode) {
                if (!ts.isEntityNameExpression(baseTypeNode.expression)) {
                    write(" extends ");
                    write(tempVarName);
                    if (baseTypeNode.typeArguments) {
                        write("<");
                        emitCommaList(baseTypeNode.typeArguments, emitType);
                        write(">");
                    }
                }
                else {
                    emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
                }
            }
            emitHeritageClause(ts.getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
            write(" {");
            writeLine();
            increaseIndent();
            emitParameterProperties(ts.getFirstConstructorWithBody(node));
            emitLines(node.members);
            decreaseIndent();
            write("}");
            writeLine();
            enclosingDeclaration = prevEnclosingDeclaration;
        }
        function writeInterfaceDeclaration(node) {
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            write("interface ");
            writeTextOfNode(currentText, node.name);
            var prevEnclosingDeclaration = enclosingDeclaration;
            enclosingDeclaration = node;
            emitTypeParameters(node.typeParameters);
            var interfaceExtendsTypes = ts.filter(ts.getInterfaceBaseTypeNodes(node), function (base) { return ts.isEntityNameExpression(base.expression); });
            if (interfaceExtendsTypes && interfaceExtendsTypes.length) {
                emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false);
            }
            write(" {");
            writeLine();
            increaseIndent();
            emitLines(node.members);
            decreaseIndent();
            write("}");
            writeLine();
            enclosingDeclaration = prevEnclosingDeclaration;
        }
        function emitPropertyDeclaration(node) {
            if (ts.hasDynamicName(node)) {
                return;
            }
            emitJsDocComments(node);
            emitClassMemberDeclarationFlags(ts.getModifierFlags(node));
            emitVariableDeclaration(node);
            write(";");
            writeLine();
        }
        function emitVariableDeclaration(node) {
            // If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
            // so there is no check needed to see if declaration is visible
            if (node.kind !== 226 /* VariableDeclaration */ || resolver.isDeclarationVisible(node)) {
                if (ts.isBindingPattern(node.name)) {
                    emitBindingPattern(node.name);
                }
                else {
                    // If this node is a computed name, it can only be a symbol, because we've already skipped
                    // it if it's not a well known symbol. In that case, the text of the name will be exactly
                    // what we want, namely the name expression enclosed in brackets.
                    writeTextOfNode(currentText, node.name);
                    // If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
                    // we don't want to emit property declaration with "?"
                    if ((node.kind === 149 /* PropertyDeclaration */ || node.kind === 148 /* PropertySignature */ ||
                        (node.kind === 146 /* Parameter */ && !ts.isParameterPropertyDeclaration(node))) && ts.hasQuestionToken(node)) {
                        write("?");
                    }
                    if ((node.kind === 149 /* PropertyDeclaration */ || node.kind === 148 /* PropertySignature */) && node.parent.kind === 163 /* TypeLiteral */) {
                        emitTypeOfVariableDeclarationFromTypeLiteral(node);
                    }
                    else if (resolver.isLiteralConstDeclaration(node)) {
                        write(" = ");
                        resolver.writeLiteralConstValue(node, writer);
                    }
                    else if (!ts.hasModifier(node, 8 /* Private */)) {
                        writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
                    }
                }
            }
            function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
                if (node.kind === 226 /* VariableDeclaration */) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
                }
                else if (node.kind === 149 /* PropertyDeclaration */ || node.kind === 148 /* PropertySignature */ ||
                    (node.kind === 146 /* Parameter */ && ts.hasModifier(node.parent, 8 /* Private */))) {
                    // TODO(jfreeman): Deal with computed properties in error reporting.
                    if (ts.hasModifier(node, 32 /* Static */)) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.kind === 229 /* ClassDeclaration */ || node.kind === 146 /* Parameter */) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        // Interfaces cannot have types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
                    }
                }
            }
            function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) {
                var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
                return diagnosticMessage !== undefined ? {
                    diagnosticMessage: diagnosticMessage,
                    errorNode: node,
                    typeName: node.name
                } : undefined;
            }
            function emitBindingPattern(bindingPattern) {
                // Only select non-omitted expression from the bindingPattern's elements.
                // We have to do this to avoid emitting trailing commas.
                // For example:
                //      original: var [, c,,] = [ 2,3,4]
                //      emitted: declare var c: number; // instead of declare var c:number, ;
                var elements = [];
                for (var _i = 0, _a = bindingPattern.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (element.kind !== 200 /* OmittedExpression */) {
                        elements.push(element);
                    }
                }
                emitCommaList(elements, emitBindingElement);
            }
            function emitBindingElement(bindingElement) {
                function getBindingElementTypeVisibilityError(symbolAccessibilityResult) {
                    var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
                    return diagnosticMessage !== undefined ? {
                        diagnosticMessage: diagnosticMessage,
                        errorNode: bindingElement,
                        typeName: bindingElement.name
                    } : undefined;
                }
                if (bindingElement.name) {
                    if (ts.isBindingPattern(bindingElement.name)) {
                        emitBindingPattern(bindingElement.name);
                    }
                    else {
                        writeTextOfNode(currentText, bindingElement.name);
                        writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError);
                    }
                }
            }
        }
        function emitTypeOfVariableDeclarationFromTypeLiteral(node) {
            // if this is property of type literal,
            // or is parameter of method/call/construct/index signature of type literal
            // emit only if type is specified
            if (node.type) {
                write(": ");
                emitType(node.type);
            }
        }
        function isVariableStatementVisible(node) {
            return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); });
        }
        function writeVariableStatement(node) {
            // If binding pattern doesn't have name, then there is nothing to be emitted for declaration file i.e. const [,] = [1,2].
            if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) {
                return;
            }
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            if (ts.isLet(node.declarationList)) {
                write("let ");
            }
            else if (ts.isConst(node.declarationList)) {
                write("const ");
            }
            else {
                write("var ");
            }
            emitCommaList(node.declarationList.declarations, emitVariableDeclaration, resolver.isDeclarationVisible);
            write(";");
            writeLine();
        }
        function emitAccessorDeclaration(node) {
            if (ts.hasDynamicName(node)) {
                return;
            }
            var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
            var accessorWithTypeAnnotation;
            if (node === accessors.firstAccessor) {
                emitJsDocComments(accessors.getAccessor);
                emitJsDocComments(accessors.setAccessor);
                emitClassMemberDeclarationFlags(ts.getModifierFlags(node) | (accessors.setAccessor ? 0 : 64 /* Readonly */));
                writeTextOfNode(currentText, node.name);
                if (!ts.hasModifier(node, 8 /* Private */)) {
                    accessorWithTypeAnnotation = node;
                    var type = getTypeAnnotationFromAccessor(node);
                    if (!type) {
                        // couldn't get type for the first accessor, try the another one
                        var anotherAccessor = node.kind === 153 /* GetAccessor */ ? accessors.setAccessor : accessors.getAccessor;
                        type = getTypeAnnotationFromAccessor(anotherAccessor);
                        if (type) {
                            accessorWithTypeAnnotation = anotherAccessor;
                        }
                    }
                    writeTypeOfDeclaration(node, type, getAccessorDeclarationTypeVisibilityError);
                }
                write(";");
                writeLine();
            }
            function getTypeAnnotationFromAccessor(accessor) {
                if (accessor) {
                    return accessor.kind === 153 /* GetAccessor */
                        ? accessor.type // Getter - return type
                        : accessor.parameters.length > 0
                            ? accessor.parameters[0].type // Setter parameter type
                            : undefined;
                }
            }
            function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) {
                var diagnosticMessage;
                if (accessorWithTypeAnnotation.kind === 154 /* SetAccessor */) {
                    // Setters have to have type named and cannot infer it so, the type should always be named
                    if (ts.hasModifier(accessorWithTypeAnnotation.parent, 32 /* Static */)) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1;
                    }
                    return {
                        diagnosticMessage: diagnosticMessage,
                        errorNode: accessorWithTypeAnnotation.parameters[0],
                        // TODO(jfreeman): Investigate why we are passing node.name instead of node.parameters[0].name
                        typeName: accessorWithTypeAnnotation.name
                    };
                }
                else {
                    if (ts.hasModifier(accessorWithTypeAnnotation, 32 /* Static */)) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0;
                    }
                    return {
                        diagnosticMessage: diagnosticMessage,
                        errorNode: accessorWithTypeAnnotation.name,
                        typeName: undefined
                    };
                }
            }
        }
        function writeFunctionDeclaration(node) {
            if (ts.hasDynamicName(node)) {
                return;
            }
            // If we are emitting Method/Constructor it isn't moduleElement and hence already determined to be emitting
            // so no need to verify if the declaration is visible
            if (!resolver.isImplementationOfOverload(node)) {
                emitJsDocComments(node);
                if (node.kind === 228 /* FunctionDeclaration */) {
                    emitModuleElementDeclarationFlags(node);
                }
                else if (node.kind === 151 /* MethodDeclaration */ || node.kind === 152 /* Constructor */) {
                    emitClassMemberDeclarationFlags(ts.getModifierFlags(node));
                }
                if (node.kind === 228 /* FunctionDeclaration */) {
                    write("function ");
                    writeTextOfNode(currentText, node.name);
                }
                else if (node.kind === 152 /* Constructor */) {
                    write("constructor");
                }
                else {
                    writeTextOfNode(currentText, node.name);
                    if (ts.hasQuestionToken(node)) {
                        write("?");
                    }
                }
                emitSignatureDeclaration(node);
            }
        }
        function emitSignatureDeclarationWithJsDocComments(node) {
            emitJsDocComments(node);
            emitSignatureDeclaration(node);
        }
        function emitSignatureDeclaration(node) {
            var prevEnclosingDeclaration = enclosingDeclaration;
            enclosingDeclaration = node;
            var closeParenthesizedFunctionType = false;
            if (node.kind === 157 /* IndexSignature */) {
                // Index signature can have readonly modifier
                emitClassMemberDeclarationFlags(ts.getModifierFlags(node));
                write("[");
            }
            else {
                if (node.kind === 152 /* Constructor */ && ts.hasModifier(node, 8 /* Private */)) {
                    write("();");
                    writeLine();
                    return;
                }
                // Construct signature or constructor type write new Signature
                if (node.kind === 156 /* ConstructSignature */ || node.kind === 161 /* ConstructorType */) {
                    write("new ");
                }
                else if (node.kind === 160 /* FunctionType */) {
                    var currentOutput = writer.getText();
                    // Do not generate incorrect type when function type with type parameters is type argument
                    // This could happen if user used space between two '<' making it error free
                    // e.g var x: A< <Tany>(a: Tany)=>Tany>;
                    if (node.typeParameters && currentOutput.charAt(currentOutput.length - 1) === "<") {
                        closeParenthesizedFunctionType = true;
                        write("(");
                    }
                }
                emitTypeParameters(node.typeParameters);
                write("(");
            }
            // Parameters
            emitCommaList(node.parameters, emitParameterDeclaration);
            if (node.kind === 157 /* IndexSignature */) {
                write("]");
            }
            else {
                write(")");
            }
            // If this is not a constructor and is not private, emit the return type
            var isFunctionTypeOrConstructorType = node.kind === 160 /* FunctionType */ || node.kind === 161 /* ConstructorType */;
            if (isFunctionTypeOrConstructorType || node.parent.kind === 163 /* TypeLiteral */) {
                // Emit type literal signature return type only if specified
                if (node.type) {
                    write(isFunctionTypeOrConstructorType ? " => " : ": ");
                    emitType(node.type);
                }
            }
            else if (node.kind !== 152 /* Constructor */ && !ts.hasModifier(node, 8 /* Private */)) {
                writeReturnTypeAtSignature(node, getReturnTypeVisibilityError);
            }
            enclosingDeclaration = prevEnclosingDeclaration;
            if (!isFunctionTypeOrConstructorType) {
                write(";");
                writeLine();
            }
            else if (closeParenthesizedFunctionType) {
                write(")");
            }
            function getReturnTypeVisibilityError(symbolAccessibilityResult) {
                var diagnosticMessage;
                switch (node.kind) {
                    case 156 /* ConstructSignature */:
                        // Interfaces cannot have return types that cannot be named
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
                        break;
                    case 155 /* CallSignature */:
                        // Interfaces cannot have return types that cannot be named
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
                        break;
                    case 157 /* IndexSignature */:
                        // Interfaces cannot have return types that cannot be named
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
                        break;
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                        if (ts.hasModifier(node, 32 /* Static */)) {
                            diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                    ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                    ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
                        }
                        else if (node.parent.kind === 229 /* ClassDeclaration */) {
                            diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                    ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                    ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
                        }
                        else {
                            // Interfaces cannot have return types that cannot be named
                            diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                                ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                                ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
                        }
                        break;
                    case 228 /* FunctionDeclaration */:
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
                        break;
                    default:
                        ts.Debug.fail("This is unknown kind for signature: " + node.kind);
                }
                return {
                    diagnosticMessage: diagnosticMessage,
                    errorNode: node.name || node
                };
            }
        }
        function emitParameterDeclaration(node) {
            increaseIndent();
            emitJsDocComments(node);
            if (node.dotDotDotToken) {
                write("...");
            }
            if (ts.isBindingPattern(node.name)) {
                // For bindingPattern, we can't simply writeTextOfNode from the source file
                // because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted.
                // Therefore, we will have to recursively emit each element in the bindingPattern.
                emitBindingPattern(node.name);
            }
            else {
                writeTextOfNode(currentText, node.name);
            }
            if (resolver.isOptionalParameter(node)) {
                write("?");
            }
            decreaseIndent();
            if (node.parent.kind === 160 /* FunctionType */ ||
                node.parent.kind === 161 /* ConstructorType */ ||
                node.parent.parent.kind === 163 /* TypeLiteral */) {
                emitTypeOfVariableDeclarationFromTypeLiteral(node);
            }
            else if (!ts.hasModifier(node.parent, 8 /* Private */)) {
                writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError);
            }
            function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) {
                var diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
                return diagnosticMessage !== undefined ? {
                    diagnosticMessage: diagnosticMessage,
                    errorNode: node,
                    typeName: node.name
                } : undefined;
            }
            function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
                switch (node.parent.kind) {
                    case 152 /* Constructor */:
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
                    case 156 /* ConstructSignature */:
                        // Interfaces cannot have parameter types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                    case 155 /* CallSignature */:
                        // Interfaces cannot have parameter types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                    case 157 /* IndexSignature */:
                        // Interfaces cannot have parameter types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                        if (ts.hasModifier(node.parent, 32 /* Static */)) {
                            return symbolAccessibilityResult.errorModuleName ?
                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                    ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                    ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                        }
                        else if (node.parent.parent.kind === 229 /* ClassDeclaration */) {
                            return symbolAccessibilityResult.errorModuleName ?
                                symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                    ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                    ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                        }
                        else {
                            // Interfaces cannot have parameter types that cannot be named
                            return symbolAccessibilityResult.errorModuleName ?
                                ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                                ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                        }
                    case 228 /* FunctionDeclaration */:
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
                    default:
                        ts.Debug.fail("This is unknown parent for parameter: " + node.parent.kind);
                }
            }
            function emitBindingPattern(bindingPattern) {
                // We have to explicitly emit square bracket and bracket because these tokens are not store inside the node.
                if (bindingPattern.kind === 174 /* ObjectBindingPattern */) {
                    write("{");
                    emitCommaList(bindingPattern.elements, emitBindingElement);
                    write("}");
                }
                else if (bindingPattern.kind === 175 /* ArrayBindingPattern */) {
                    write("[");
                    var elements = bindingPattern.elements;
                    emitCommaList(elements, emitBindingElement);
                    if (elements && elements.hasTrailingComma) {
                        write(", ");
                    }
                    write("]");
                }
            }
            function emitBindingElement(bindingElement) {
                if (bindingElement.kind === 200 /* OmittedExpression */) {
                    // If bindingElement is an omittedExpression (i.e. containing elision),
                    // we will emit blank space (although this may differ from users' original code,
                    // it allows emitSeparatedList to write separator appropriately)
                    // Example:
                    //      original: function foo([, x, ,]) {}
                    //      emit    : function foo([ , x,  , ]) {}
                    write(" ");
                }
                else if (bindingElement.kind === 176 /* BindingElement */) {
                    if (bindingElement.propertyName) {
                        // bindingElement has propertyName property in the following case:
                        //      { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y"
                        // We have to explicitly emit the propertyName before descending into its binding elements.
                        // Example:
                        //      original: function foo({y: [a,b,c]}) {}
                        //      emit    : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
                        writeTextOfNode(currentText, bindingElement.propertyName);
                        write(": ");
                    }
                    if (bindingElement.name) {
                        if (ts.isBindingPattern(bindingElement.name)) {
                            // If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
                            // In the case of rest element, we will omit rest element.
                            // Example:
                            //      original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {}
                            //      emit    : declare function foo([a, [[b]], c]: [number, [[string]], number]): void;
                            //      original with rest: function foo([a, ...c]) {}
                            //      emit              : declare function foo([a, ...c]): void;
                            emitBindingPattern(bindingElement.name);
                        }
                        else {
                            ts.Debug.assert(bindingElement.name.kind === 71 /* Identifier */);
                            // If the node is just an identifier, we will simply emit the text associated with the node's name
                            // Example:
                            //      original: function foo({y = 10, x}) {}
                            //      emit    : declare function foo({y, x}: {number, any}): void;
                            if (bindingElement.dotDotDotToken) {
                                write("...");
                            }
                            writeTextOfNode(currentText, bindingElement.name);
                        }
                    }
                }
            }
        }
        function emitNode(node) {
            switch (node.kind) {
                case 228 /* FunctionDeclaration */:
                case 233 /* ModuleDeclaration */:
                case 237 /* ImportEqualsDeclaration */:
                case 230 /* InterfaceDeclaration */:
                case 229 /* ClassDeclaration */:
                case 231 /* TypeAliasDeclaration */:
                case 232 /* EnumDeclaration */:
                    return emitModuleElement(node, isModuleElementVisible(node));
                case 208 /* VariableStatement */:
                    return emitModuleElement(node, isVariableStatementVisible(node));
                case 238 /* ImportDeclaration */:
                    // Import declaration without import clause is visible, otherwise it is not visible
                    return emitModuleElement(node, /*isModuleElementVisible*/ !node.importClause);
                case 244 /* ExportDeclaration */:
                    return emitExportDeclaration(node);
                case 152 /* Constructor */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                    return writeFunctionDeclaration(node);
                case 156 /* ConstructSignature */:
                case 155 /* CallSignature */:
                case 157 /* IndexSignature */:
                    return emitSignatureDeclarationWithJsDocComments(node);
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return emitAccessorDeclaration(node);
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    return emitPropertyDeclaration(node);
                case 264 /* EnumMember */:
                    return emitEnumMemberDeclaration(node);
                case 243 /* ExportAssignment */:
                    return emitExportAssignment(node);
                case 265 /* SourceFile */:
                    return emitSourceFile(node);
            }
        }
        /**
         * Adds the reference to referenced file, returns true if global file reference was emitted
         * @param referencedFile
         * @param addBundledFileReference Determines if global file reference corresponding to bundled file should be emitted or not
         */
        function writeReferencePath(referencedFile, addBundledFileReference, emitOnlyDtsFiles) {
            var declFileName;
            var addedBundledEmitReference = false;
            if (referencedFile.isDeclarationFile) {
                // Declaration file, use declaration file name
                declFileName = referencedFile.fileName;
            }
            else {
                // Get the declaration file path
                ts.forEachEmittedFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles);
            }
            if (declFileName) {
                declFileName = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizeSlashes(declarationFilePath)), declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
                /*isAbsolutePathAnUrl*/ false);
                referencesOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
            }
            return addedBundledEmitReference;
            function getDeclFileName(emitFileNames, sourceFileOrBundle) {
                // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
                var isBundledEmit = sourceFileOrBundle.kind === 266 /* Bundle */;
                if (isBundledEmit && !addBundledFileReference) {
                    return;
                }
                ts.Debug.assert(!!emitFileNames.declarationFilePath || ts.isSourceFileJavaScript(referencedFile), "Declaration file is not present only for javascript files");
                declFileName = emitFileNames.declarationFilePath || emitFileNames.jsFilePath;
                addedBundledEmitReference = isBundledEmit;
            }
        }
    }
    /* @internal */
    function writeDeclarationFile(declarationFilePath, sourceFileOrBundle, host, resolver, emitterDiagnostics, emitOnlyDtsFiles) {
        var emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
        var emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
        if (!emitSkipped) {
            var sourceFiles = sourceFileOrBundle.kind === 266 /* Bundle */ ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
            var declarationOutput = emitDeclarationResult.referencesOutput
                + getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
            ts.writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles);
        }
        return emitSkipped;
        function getDeclarationOutput(synchronousDeclarationOutput, moduleElementDeclarationEmitInfo) {
            var appliedSyncOutputPos = 0;
            var declarationOutput = "";
            // apply asynchronous additions to the synchronous output
            ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
                if (aliasEmitInfo.asynchronousOutput) {
                    declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos, aliasEmitInfo.outputPos);
                    declarationOutput += getDeclarationOutput(aliasEmitInfo.asynchronousOutput, aliasEmitInfo.subModuleElementDeclarationEmitInfo);
                    appliedSyncOutputPos = aliasEmitInfo.outputPos;
                }
            });
            declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos);
            return declarationOutput;
        }
    }
    ts.writeDeclarationFile = writeDeclarationFile;
})(ts || (ts = {}));
/// <reference path="checker.ts" />
/// <reference path="transformer.ts" />
/// <reference path="declarationEmitter.ts" />
/// <reference path="sourcemap.ts" />
/// <reference path="comments.ts" />
var ts;
(function (ts) {
    var delimiters = createDelimiterMap();
    var brackets = createBracketsMap();
    /*@internal*/
    /**
     * Iterates over the source files that are expected to have an emit output.
     *
     * @param host An EmitHost.
     * @param action The action to execute.
     * @param sourceFilesOrTargetSourceFile
     *   If an array, the full list of source files to emit.
     *   Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
     */
    function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, emitOnlyDtsFiles) {
        var sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
        var options = host.getCompilerOptions();
        if (options.outFile || options.out) {
            if (sourceFiles.length) {
                var jsFilePath = options.outFile || options.out;
                var sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
                var declarationFilePath = options.declaration ? ts.removeFileExtension(jsFilePath) + ".d.ts" /* Dts */ : "";
                action({ jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath }, ts.createBundle(sourceFiles), emitOnlyDtsFiles);
            }
        }
        else {
            for (var _a = 0, sourceFiles_1 = sourceFiles; _a < sourceFiles_1.length; _a++) {
                var sourceFile = sourceFiles_1[_a];
                var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
                var sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
                var declarationFilePath = !ts.isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? ts.getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
                action({ jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath }, sourceFile, emitOnlyDtsFiles);
            }
        }
    }
    ts.forEachEmittedFile = forEachEmittedFile;
    function getSourceMapFilePath(jsFilePath, options) {
        return options.sourceMap ? jsFilePath + ".map" : undefined;
    }
    // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
    // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
    // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
    function getOutputExtension(sourceFile, options) {
        if (options.jsx === 1 /* Preserve */) {
            if (ts.isSourceFileJavaScript(sourceFile)) {
                if (ts.fileExtensionIs(sourceFile.fileName, ".jsx" /* Jsx */)) {
                    return ".jsx" /* Jsx */;
                }
            }
            else if (sourceFile.languageVariant === 1 /* JSX */) {
                // TypeScript source file preserving JSX syntax
                return ".jsx" /* Jsx */;
            }
        }
        return ".js" /* Js */;
    }
    function getOriginalSourceFileOrBundle(sourceFileOrBundle) {
        if (sourceFileOrBundle.kind === 266 /* Bundle */) {
            return ts.updateBundle(sourceFileOrBundle, ts.sameMap(sourceFileOrBundle.sourceFiles, ts.getOriginalSourceFile));
        }
        return ts.getOriginalSourceFile(sourceFileOrBundle);
    }
    /*@internal*/
    // 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, emitOnlyDtsFiles, transformers) {
        var compilerOptions = host.getCompilerOptions();
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var sourceMapDataList = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
        var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined;
        var emitterDiagnostics = ts.createDiagnosticCollection();
        var newLine = host.getNewLine();
        var writer = ts.createTextWriter(newLine);
        var sourceMap = ts.createSourceMapWriter(host, writer);
        var currentSourceFile;
        var bundledHelpers;
        var isOwnFileEmit;
        var emitSkipped = false;
        var sourceFiles = ts.getSourceFilesToEmit(host, targetSourceFile);
        // Transform the source files
        var transform = ts.transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false);
        // Create a printer to print the nodes
        var printer = createPrinter(compilerOptions, {
            // resolver hooks
            hasGlobalName: resolver.hasGlobalName,
            // transform hooks
            onEmitNode: transform.emitNodeWithNotification,
            substituteNode: transform.substituteNode,
            // sourcemap hooks
            onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap,
            onEmitSourceMapOfToken: sourceMap.emitTokenWithSourceMap,
            onEmitSourceMapOfPosition: sourceMap.emitPos,
            // emitter hooks
            onEmitHelpers: emitHelpers,
            onSetSourceFile: setSourceFile,
        });
        // Emit each output file
        ts.performance.mark("beforePrint");
        forEachEmittedFile(host, emitSourceFileOrBundle, transform.transformed, emitOnlyDtsFiles);
        ts.performance.measure("printTime", "beforePrint");
        // Clean up emit nodes on parse tree
        transform.dispose();
        return {
            emitSkipped: emitSkipped,
            diagnostics: emitterDiagnostics.getDiagnostics(),
            emittedFiles: emittedFilesList,
            sourceMaps: sourceMapDataList
        };
        function emitSourceFileOrBundle(_a, sourceFileOrBundle) {
            var jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath;
            // Make sure not to write js file and source map file if any of them cannot be written
            if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) {
                if (!emitOnlyDtsFiles) {
                    printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle);
                }
            }
            else {
                emitSkipped = true;
            }
            if (declarationFilePath) {
                emitSkipped = ts.writeDeclarationFile(declarationFilePath, getOriginalSourceFileOrBundle(sourceFileOrBundle), host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped;
            }
            if (!emitSkipped && emittedFilesList) {
                if (!emitOnlyDtsFiles) {
                    emittedFilesList.push(jsFilePath);
                }
                if (sourceMapFilePath) {
                    emittedFilesList.push(sourceMapFilePath);
                }
                if (declarationFilePath) {
                    emittedFilesList.push(declarationFilePath);
                }
            }
        }
        function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle) {
            var bundle = sourceFileOrBundle.kind === 266 /* Bundle */ ? sourceFileOrBundle : undefined;
            var sourceFile = sourceFileOrBundle.kind === 265 /* SourceFile */ ? sourceFileOrBundle : undefined;
            var sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
            sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFileOrBundle);
            if (bundle) {
                bundledHelpers = ts.createMap();
                isOwnFileEmit = false;
                printer.writeBundle(bundle, writer);
            }
            else {
                isOwnFileEmit = true;
                printer.writeFile(sourceFile, writer);
            }
            writer.writeLine();
            var sourceMappingURL = sourceMap.getSourceMappingURL();
            if (sourceMappingURL) {
                writer.write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Sometimes tools can sometimes see this line as a source mapping url comment
            }
            // Write the source map
            if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) {
                ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles);
            }
            // Record source map data for the test harness.
            if (sourceMapDataList) {
                sourceMapDataList.push(sourceMap.getSourceMapData());
            }
            // Write the output file
            ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles);
            // Reset state
            sourceMap.reset();
            writer.reset();
            currentSourceFile = undefined;
            bundledHelpers = undefined;
            isOwnFileEmit = false;
        }
        function setSourceFile(node) {
            currentSourceFile = node;
            sourceMap.setSourceFile(node);
        }
        function emitHelpers(node, writeLines) {
            var helpersEmitted = false;
            var bundle = node.kind === 266 /* Bundle */ ? node : undefined;
            if (bundle && moduleKind === ts.ModuleKind.None) {
                return;
            }
            var numNodes = bundle ? bundle.sourceFiles.length : 1;
            for (var i = 0; i < numNodes; i++) {
                var currentNode = bundle ? bundle.sourceFiles[i] : node;
                var sourceFile = ts.isSourceFile(currentNode) ? currentNode : currentSourceFile;
                var shouldSkip = compilerOptions.noEmitHelpers || ts.getExternalHelpersModuleName(sourceFile) !== undefined;
                var shouldBundle = ts.isSourceFile(currentNode) && !isOwnFileEmit;
                var helpers = ts.getEmitHelpers(currentNode);
                if (helpers) {
                    for (var _a = 0, _b = ts.stableSort(helpers, ts.compareEmitHelpers); _a < _b.length; _a++) {
                        var helper = _b[_a];
                        if (!helper.scoped) {
                            // Skip the helper if it can be skipped and the noEmitHelpers compiler
                            // option is set, or if it can be imported and the importHelpers compiler
                            // option is set.
                            if (shouldSkip)
                                continue;
                            // Skip the helper if it can be bundled but hasn't already been emitted and we
                            // are emitting a bundled module.
                            if (shouldBundle) {
                                if (bundledHelpers.get(helper.name)) {
                                    continue;
                                }
                                bundledHelpers.set(helper.name, true);
                            }
                        }
                        else if (bundle) {
                            // Skip the helper if it is scoped and we are emitting bundled helpers
                            continue;
                        }
                        writeLines(helper.text);
                        helpersEmitted = true;
                    }
                }
            }
            return helpersEmitted;
        }
    }
    ts.emitFiles = emitFiles;
    function createPrinter(printerOptions, handlers) {
        if (printerOptions === void 0) { printerOptions = {}; }
        if (handlers === void 0) { handlers = {}; }
        var hasGlobalName = handlers.hasGlobalName, onEmitSourceMapOfNode = handlers.onEmitSourceMapOfNode, onEmitSourceMapOfToken = handlers.onEmitSourceMapOfToken, onEmitSourceMapOfPosition = handlers.onEmitSourceMapOfPosition, onEmitNode = handlers.onEmitNode, onEmitHelpers = handlers.onEmitHelpers, onSetSourceFile = handlers.onSetSourceFile, substituteNode = handlers.substituteNode, onBeforeEmitNodeArray = handlers.onBeforeEmitNodeArray, onAfterEmitNodeArray = handlers.onAfterEmitNodeArray, onBeforeEmitToken = handlers.onBeforeEmitToken, onAfterEmitToken = handlers.onAfterEmitToken;
        var newLine = ts.getNewLineCharacter(printerOptions);
        var comments = ts.createCommentWriter(printerOptions, onEmitSourceMapOfPosition);
        var emitNodeWithComments = comments.emitNodeWithComments, emitBodyWithDetachedComments = comments.emitBodyWithDetachedComments, emitTrailingCommentsOfPosition = comments.emitTrailingCommentsOfPosition, emitLeadingCommentsOfPosition = comments.emitLeadingCommentsOfPosition;
        var currentSourceFile;
        var nodeIdToGeneratedName; // Map of generated names for specific nodes.
        var autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables.
        var generatedNames; // Set of names generated by the NameGenerator.
        var tempFlagsStack; // Stack of enclosing name generation scopes.
        var tempFlags; // TempFlags for the current name generation scope.
        var writer;
        var ownWriter;
        reset();
        return {
            // public API
            printNode: printNode,
            printFile: printFile,
            printBundle: printBundle,
            // internal API
            writeNode: writeNode,
            writeFile: writeFile,
            writeBundle: writeBundle
        };
        function printNode(hint, node, sourceFile) {
            switch (hint) {
                case 0 /* SourceFile */:
                    ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node.");
                    break;
                case 2 /* IdentifierName */:
                    ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node.");
                    break;
                case 1 /* Expression */:
                    ts.Debug.assert(ts.isExpression(node), "Expected an Expression node.");
                    break;
            }
            switch (node.kind) {
                case 265 /* SourceFile */: return printFile(node);
                case 266 /* Bundle */: return printBundle(node);
            }
            writeNode(hint, node, sourceFile, beginPrint());
            return endPrint();
        }
        function printBundle(bundle) {
            writeBundle(bundle, beginPrint());
            return endPrint();
        }
        function printFile(sourceFile) {
            writeFile(sourceFile, beginPrint());
            return endPrint();
        }
        function writeNode(hint, node, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output);
            print(hint, node, sourceFile);
            reset();
            writer = previousWriter;
        }
        function writeBundle(bundle, output) {
            var previousWriter = writer;
            setWriter(output);
            emitShebangIfNeeded(bundle);
            emitPrologueDirectivesIfNeeded(bundle);
            emitHelpersIndirect(bundle);
            for (var _a = 0, _b = bundle.sourceFiles; _a < _b.length; _a++) {
                var sourceFile = _b[_a];
                print(0 /* SourceFile */, sourceFile, sourceFile);
            }
            reset();
            writer = previousWriter;
        }
        function writeFile(sourceFile, output) {
            var previousWriter = writer;
            setWriter(output);
            emitShebangIfNeeded(sourceFile);
            emitPrologueDirectivesIfNeeded(sourceFile);
            print(0 /* SourceFile */, sourceFile, sourceFile);
            reset();
            writer = previousWriter;
        }
        function beginPrint() {
            return ownWriter || (ownWriter = ts.createTextWriter(newLine));
        }
        function endPrint() {
            var text = ownWriter.getText();
            ownWriter.reset();
            return text;
        }
        function print(hint, node, sourceFile) {
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            pipelineEmitWithNotification(hint, node);
        }
        function setSourceFile(sourceFile) {
            currentSourceFile = sourceFile;
            comments.setSourceFile(sourceFile);
            if (onSetSourceFile) {
                onSetSourceFile(sourceFile);
            }
        }
        function setWriter(output) {
            writer = output;
            comments.setWriter(output);
        }
        function reset() {
            nodeIdToGeneratedName = [];
            autoGeneratedIdToGeneratedName = [];
            generatedNames = ts.createMap();
            tempFlagsStack = [];
            tempFlags = 0 /* Auto */;
            comments.reset();
            setWriter(/*output*/ undefined);
        }
        // TODO: Should this just be `emit`?
        // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034
        function emitIfPresent(node) {
            if (node) {
                emit(node);
            }
        }
        function emit(node) {
            pipelineEmitWithNotification(4 /* Unspecified */, node);
        }
        function emitIdentifierName(node) {
            pipelineEmitWithNotification(2 /* IdentifierName */, node);
        }
        function emitExpression(node) {
            pipelineEmitWithNotification(1 /* Expression */, node);
        }
        function pipelineEmitWithNotification(hint, node) {
            if (onEmitNode) {
                onEmitNode(hint, node, pipelineEmitWithComments);
            }
            else {
                pipelineEmitWithComments(hint, node);
            }
        }
        function pipelineEmitWithComments(hint, node) {
            node = trySubstituteNode(hint, node);
            if (emitNodeWithComments && hint !== 0 /* SourceFile */) {
                emitNodeWithComments(hint, node, pipelineEmitWithSourceMap);
            }
            else {
                pipelineEmitWithSourceMap(hint, node);
            }
        }
        function pipelineEmitWithSourceMap(hint, node) {
            if (onEmitSourceMapOfNode && hint !== 0 /* SourceFile */ && hint !== 2 /* IdentifierName */) {
                onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
            }
            else {
                pipelineEmitWithHint(hint, node);
            }
        }
        function pipelineEmitWithHint(hint, node) {
            switch (hint) {
                case 0 /* SourceFile */: return pipelineEmitSourceFile(node);
                case 2 /* IdentifierName */: return pipelineEmitIdentifierName(node);
                case 1 /* Expression */: return pipelineEmitExpression(node);
                case 3 /* MappedTypeParameter */: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration));
                case 4 /* Unspecified */: return pipelineEmitUnspecified(node);
            }
        }
        function pipelineEmitSourceFile(node) {
            ts.Debug.assertNode(node, ts.isSourceFile);
            emitSourceFile(node);
        }
        function pipelineEmitIdentifierName(node) {
            ts.Debug.assertNode(node, ts.isIdentifier);
            emitIdentifier(node);
        }
        function emitMappedTypeParameter(node) {
            emit(node.name);
            write(" in ");
            emit(node.constraint);
        }
        function pipelineEmitUnspecified(node) {
            var kind = node.kind;
            // Reserved words
            // Strict mode reserved words
            // Contextual keywords
            if (ts.isKeyword(kind)) {
                writeTokenNode(node);
                return;
            }
            switch (kind) {
                // Pseudo-literals
                case 14 /* TemplateHead */:
                case 15 /* TemplateMiddle */:
                case 16 /* TemplateTail */:
                    return emitLiteral(node);
                // Identifiers
                case 71 /* Identifier */:
                    return emitIdentifier(node);
                // Parse tree nodes
                // Names
                case 143 /* QualifiedName */:
                    return emitQualifiedName(node);
                case 144 /* ComputedPropertyName */:
                    return emitComputedPropertyName(node);
                // Signature elements
                case 145 /* TypeParameter */:
                    return emitTypeParameter(node);
                case 146 /* Parameter */:
                    return emitParameter(node);
                case 147 /* Decorator */:
                    return emitDecorator(node);
                // Type members
                case 148 /* PropertySignature */:
                    return emitPropertySignature(node);
                case 149 /* PropertyDeclaration */:
                    return emitPropertyDeclaration(node);
                case 150 /* MethodSignature */:
                    return emitMethodSignature(node);
                case 151 /* MethodDeclaration */:
                    return emitMethodDeclaration(node);
                case 152 /* Constructor */:
                    return emitConstructor(node);
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return emitAccessorDeclaration(node);
                case 155 /* CallSignature */:
                    return emitCallSignature(node);
                case 156 /* ConstructSignature */:
                    return emitConstructSignature(node);
                case 157 /* IndexSignature */:
                    return emitIndexSignature(node);
                // Types
                case 158 /* TypePredicate */:
                    return emitTypePredicate(node);
                case 159 /* TypeReference */:
                    return emitTypeReference(node);
                case 160 /* FunctionType */:
                    return emitFunctionType(node);
                case 273 /* JSDocFunctionType */:
                    return emitJSDocFunctionType(node);
                case 161 /* ConstructorType */:
                    return emitConstructorType(node);
                case 162 /* TypeQuery */:
                    return emitTypeQuery(node);
                case 163 /* TypeLiteral */:
                    return emitTypeLiteral(node);
                case 164 /* ArrayType */:
                    return emitArrayType(node);
                case 165 /* TupleType */:
                    return emitTupleType(node);
                case 166 /* UnionType */:
                    return emitUnionType(node);
                case 167 /* IntersectionType */:
                    return emitIntersectionType(node);
                case 168 /* ParenthesizedType */:
                    return emitParenthesizedType(node);
                case 201 /* ExpressionWithTypeArguments */:
                    return emitExpressionWithTypeArguments(node);
                case 169 /* ThisType */:
                    return emitThisType();
                case 170 /* TypeOperator */:
                    return emitTypeOperator(node);
                case 171 /* IndexedAccessType */:
                    return emitIndexedAccessType(node);
                case 172 /* MappedType */:
                    return emitMappedType(node);
                case 173 /* LiteralType */:
                    return emitLiteralType(node);
                case 268 /* JSDocAllType */:
                    write("*");
                    return;
                case 269 /* JSDocUnknownType */:
                    write("?");
                    return;
                case 270 /* JSDocNullableType */:
                    return emitJSDocNullableType(node);
                case 271 /* JSDocNonNullableType */:
                    return emitJSDocNonNullableType(node);
                case 272 /* JSDocOptionalType */:
                    return emitJSDocOptionalType(node);
                case 274 /* JSDocVariadicType */:
                    return emitJSDocVariadicType(node);
                // Binding patterns
                case 174 /* ObjectBindingPattern */:
                    return emitObjectBindingPattern(node);
                case 175 /* ArrayBindingPattern */:
                    return emitArrayBindingPattern(node);
                case 176 /* BindingElement */:
                    return emitBindingElement(node);
                // Misc
                case 205 /* TemplateSpan */:
                    return emitTemplateSpan(node);
                case 206 /* SemicolonClassElement */:
                    return emitSemicolonClassElement();
                // Statements
                case 207 /* Block */:
                    return emitBlock(node);
                case 208 /* VariableStatement */:
                    return emitVariableStatement(node);
                case 209 /* EmptyStatement */:
                    return emitEmptyStatement();
                case 210 /* ExpressionStatement */:
                    return emitExpressionStatement(node);
                case 211 /* IfStatement */:
                    return emitIfStatement(node);
                case 212 /* DoStatement */:
                    return emitDoStatement(node);
                case 213 /* WhileStatement */:
                    return emitWhileStatement(node);
                case 214 /* ForStatement */:
                    return emitForStatement(node);
                case 215 /* ForInStatement */:
                    return emitForInStatement(node);
                case 216 /* ForOfStatement */:
                    return emitForOfStatement(node);
                case 217 /* ContinueStatement */:
                    return emitContinueStatement(node);
                case 218 /* BreakStatement */:
                    return emitBreakStatement(node);
                case 219 /* ReturnStatement */:
                    return emitReturnStatement(node);
                case 220 /* WithStatement */:
                    return emitWithStatement(node);
                case 221 /* SwitchStatement */:
                    return emitSwitchStatement(node);
                case 222 /* LabeledStatement */:
                    return emitLabeledStatement(node);
                case 223 /* ThrowStatement */:
                    return emitThrowStatement(node);
                case 224 /* TryStatement */:
                    return emitTryStatement(node);
                case 225 /* DebuggerStatement */:
                    return emitDebuggerStatement(node);
                // Declarations
                case 226 /* VariableDeclaration */:
                    return emitVariableDeclaration(node);
                case 227 /* VariableDeclarationList */:
                    return emitVariableDeclarationList(node);
                case 228 /* FunctionDeclaration */:
                    return emitFunctionDeclaration(node);
                case 229 /* ClassDeclaration */:
                    return emitClassDeclaration(node);
                case 230 /* InterfaceDeclaration */:
                    return emitInterfaceDeclaration(node);
                case 231 /* TypeAliasDeclaration */:
                    return emitTypeAliasDeclaration(node);
                case 232 /* EnumDeclaration */:
                    return emitEnumDeclaration(node);
                case 233 /* ModuleDeclaration */:
                    return emitModuleDeclaration(node);
                case 234 /* ModuleBlock */:
                    return emitModuleBlock(node);
                case 235 /* CaseBlock */:
                    return emitCaseBlock(node);
                case 236 /* NamespaceExportDeclaration */:
                    return emitNamespaceExportDeclaration(node);
                case 237 /* ImportEqualsDeclaration */:
                    return emitImportEqualsDeclaration(node);
                case 238 /* ImportDeclaration */:
                    return emitImportDeclaration(node);
                case 239 /* ImportClause */:
                    return emitImportClause(node);
                case 240 /* NamespaceImport */:
                    return emitNamespaceImport(node);
                case 241 /* NamedImports */:
                    return emitNamedImports(node);
                case 242 /* ImportSpecifier */:
                    return emitImportSpecifier(node);
                case 243 /* ExportAssignment */:
                    return emitExportAssignment(node);
                case 244 /* ExportDeclaration */:
                    return emitExportDeclaration(node);
                case 245 /* NamedExports */:
                    return emitNamedExports(node);
                case 246 /* ExportSpecifier */:
                    return emitExportSpecifier(node);
                case 247 /* MissingDeclaration */:
                    return;
                // Module references
                case 248 /* ExternalModuleReference */:
                    return emitExternalModuleReference(node);
                // JSX (non-expression)
                case 10 /* JsxText */:
                    return emitJsxText(node);
                case 251 /* JsxOpeningElement */:
                    return emitJsxOpeningElement(node);
                case 252 /* JsxClosingElement */:
                    return emitJsxClosingElement(node);
                case 253 /* JsxAttribute */:
                    return emitJsxAttribute(node);
                case 254 /* JsxAttributes */:
                    return emitJsxAttributes(node);
                case 255 /* JsxSpreadAttribute */:
                    return emitJsxSpreadAttribute(node);
                case 256 /* JsxExpression */:
                    return emitJsxExpression(node);
                // Clauses
                case 257 /* CaseClause */:
                    return emitCaseClause(node);
                case 258 /* DefaultClause */:
                    return emitDefaultClause(node);
                case 259 /* HeritageClause */:
                    return emitHeritageClause(node);
                case 260 /* CatchClause */:
                    return emitCatchClause(node);
                // Property assignments
                case 261 /* PropertyAssignment */:
                    return emitPropertyAssignment(node);
                case 262 /* ShorthandPropertyAssignment */:
                    return emitShorthandPropertyAssignment(node);
                case 263 /* SpreadAssignment */:
                    return emitSpreadAssignment(node);
                // Enum
                case 264 /* EnumMember */:
                    return emitEnumMember(node);
            }
            // If the node is an expression, try to emit it as an expression with
            // substitution.
            if (ts.isExpression(node)) {
                return pipelineEmitExpression(trySubstituteNode(1 /* Expression */, node));
            }
            if (ts.isToken(node)) {
                writeTokenNode(node);
                return;
            }
        }
        function pipelineEmitExpression(node) {
            var kind = node.kind;
            switch (kind) {
                // Literals
                case 8 /* NumericLiteral */:
                    return emitNumericLiteral(node);
                case 9 /* StringLiteral */:
                case 12 /* RegularExpressionLiteral */:
                case 13 /* NoSubstitutionTemplateLiteral */:
                    return emitLiteral(node);
                // Identifiers
                case 71 /* Identifier */:
                    return emitIdentifier(node);
                // Reserved words
                case 86 /* FalseKeyword */:
                case 95 /* NullKeyword */:
                case 97 /* SuperKeyword */:
                case 101 /* TrueKeyword */:
                case 99 /* ThisKeyword */:
                case 91 /* ImportKeyword */:
                    writeTokenNode(node);
                    return;
                // Expressions
                case 177 /* ArrayLiteralExpression */:
                    return emitArrayLiteralExpression(node);
                case 178 /* ObjectLiteralExpression */:
                    return emitObjectLiteralExpression(node);
                case 179 /* PropertyAccessExpression */:
                    return emitPropertyAccessExpression(node);
                case 180 /* ElementAccessExpression */:
                    return emitElementAccessExpression(node);
                case 181 /* CallExpression */:
                    return emitCallExpression(node);
                case 182 /* NewExpression */:
                    return emitNewExpression(node);
                case 183 /* TaggedTemplateExpression */:
                    return emitTaggedTemplateExpression(node);
                case 184 /* TypeAssertionExpression */:
                    return emitTypeAssertionExpression(node);
                case 185 /* ParenthesizedExpression */:
                    return emitParenthesizedExpression(node);
                case 186 /* FunctionExpression */:
                    return emitFunctionExpression(node);
                case 187 /* ArrowFunction */:
                    return emitArrowFunction(node);
                case 188 /* DeleteExpression */:
                    return emitDeleteExpression(node);
                case 189 /* TypeOfExpression */:
                    return emitTypeOfExpression(node);
                case 190 /* VoidExpression */:
                    return emitVoidExpression(node);
                case 191 /* AwaitExpression */:
                    return emitAwaitExpression(node);
                case 192 /* PrefixUnaryExpression */:
                    return emitPrefixUnaryExpression(node);
                case 193 /* PostfixUnaryExpression */:
                    return emitPostfixUnaryExpression(node);
                case 194 /* BinaryExpression */:
                    return emitBinaryExpression(node);
                case 195 /* ConditionalExpression */:
                    return emitConditionalExpression(node);
                case 196 /* TemplateExpression */:
                    return emitTemplateExpression(node);
                case 197 /* YieldExpression */:
                    return emitYieldExpression(node);
                case 198 /* SpreadElement */:
                    return emitSpreadExpression(node);
                case 199 /* ClassExpression */:
                    return emitClassExpression(node);
                case 200 /* OmittedExpression */:
                    return;
                case 202 /* AsExpression */:
                    return emitAsExpression(node);
                case 203 /* NonNullExpression */:
                    return emitNonNullExpression(node);
                case 204 /* MetaProperty */:
                    return emitMetaProperty(node);
                // JSX
                case 249 /* JsxElement */:
                    return emitJsxElement(node);
                case 250 /* JsxSelfClosingElement */:
                    return emitJsxSelfClosingElement(node);
                // Transformation nodes
                case 288 /* PartiallyEmittedExpression */:
                    return emitPartiallyEmittedExpression(node);
                case 289 /* CommaListExpression */:
                    return emitCommaList(node);
            }
        }
        function trySubstituteNode(hint, node) {
            return node && substituteNode && substituteNode(hint, node) || node;
        }
        function emitHelpersIndirect(node) {
            if (onEmitHelpers) {
                onEmitHelpers(node, writeLines);
            }
        }
        //
        // Literals/Pseudo-literals
        //
        // SyntaxKind.NumericLiteral
        function emitNumericLiteral(node) {
            emitLiteral(node);
        }
        // SyntaxKind.StringLiteral
        // SyntaxKind.RegularExpressionLiteral
        // SyntaxKind.NoSubstitutionTemplateLiteral
        // SyntaxKind.TemplateHead
        // SyntaxKind.TemplateMiddle
        // SyntaxKind.TemplateTail
        function emitLiteral(node) {
            var text = getLiteralTextOfNode(node);
            if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
                && (node.kind === 9 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
                writer.writeLiteral(text);
            }
            else {
                write(text);
            }
        }
        //
        // Identifiers
        //
        function emitIdentifier(node) {
            write(getTextOfNode(node, /*includeTrivia*/ false));
            emitTypeArguments(node, node.typeArguments);
        }
        //
        // Names
        //
        function emitQualifiedName(node) {
            emitEntityName(node.left);
            write(".");
            emit(node.right);
        }
        function emitEntityName(node) {
            if (node.kind === 71 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitComputedPropertyName(node) {
            write("[");
            emitExpression(node.expression);
            write("]");
        }
        //
        // Signature elements
        //
        function emitTypeParameter(node) {
            emit(node.name);
            emitWithPrefix(" extends ", node.constraint);
            emitWithPrefix(" = ", node.default);
        }
        function emitParameter(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitIfPresent(node.dotDotDotToken);
            if (node.name) {
                emit(node.name);
            }
            emitIfPresent(node.questionToken);
            if (node.parent && node.parent.kind === 273 /* JSDocFunctionType */ && !node.name) {
                emit(node.type);
            }
            else {
                emitWithPrefix(": ", node.type);
            }
            emitExpressionWithPrefix(" = ", node.initializer);
        }
        function emitDecorator(decorator) {
            write("@");
            emitExpression(decorator.expression);
        }
        //
        // Type members
        //
        function emitPropertySignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emitIfPresent(node.questionToken);
            emitWithPrefix(": ", node.type);
            write(";");
        }
        function emitPropertyDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emitIfPresent(node.questionToken);
            emitWithPrefix(": ", node.type);
            emitExpressionWithPrefix(" = ", node.initializer);
            write(";");
        }
        function emitMethodSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emitIfPresent(node.questionToken);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitWithPrefix(": ", node.type);
            write(";");
        }
        function emitMethodDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitIfPresent(node.asteriskToken);
            emit(node.name);
            emitIfPresent(node.questionToken);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitConstructor(node) {
            emitModifiers(node, node.modifiers);
            write("constructor");
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitAccessorDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            write(node.kind === 153 /* GetAccessor */ ? "get " : "set ");
            emit(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitCallSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitWithPrefix(": ", node.type);
            write(";");
        }
        function emitConstructSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            write("new ");
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitWithPrefix(": ", node.type);
            write(";");
        }
        function emitIndexSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitParametersForIndexSignature(node, node.parameters);
            emitWithPrefix(": ", node.type);
            write(";");
        }
        function emitSemicolonClassElement() {
            write(";");
        }
        //
        // Types
        //
        function emitTypePredicate(node) {
            emit(node.parameterName);
            write(" is ");
            emit(node.type);
        }
        function emitTypeReference(node) {
            emit(node.typeName);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitFunctionType(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            write(" => ");
            emit(node.type);
        }
        function emitJSDocFunctionType(node) {
            write("function");
            emitParameters(node, node.parameters);
            write(":");
            emit(node.type);
        }
        function emitJSDocNullableType(node) {
            write("?");
            emit(node.type);
        }
        function emitJSDocNonNullableType(node) {
            write("!");
            emit(node.type);
        }
        function emitJSDocOptionalType(node) {
            emit(node.type);
            write("=");
        }
        function emitConstructorType(node) {
            write("new ");
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            write(" => ");
            emit(node.type);
        }
        function emitTypeQuery(node) {
            write("typeof ");
            emit(node.exprName);
        }
        function emitTypeLiteral(node) {
            write("{");
            var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */;
            emitList(node, node.members, flags | 262144 /* NoSpaceIfEmpty */);
            write("}");
        }
        function emitArrayType(node) {
            emit(node.elementType);
            write("[]");
        }
        function emitJSDocVariadicType(node) {
            write("...");
            emit(node.type);
        }
        function emitTupleType(node) {
            write("[");
            emitList(node, node.elementTypes, 336 /* TupleTypeElements */);
            write("]");
        }
        function emitUnionType(node) {
            emitList(node, node.types, 260 /* UnionTypeConstituents */);
        }
        function emitIntersectionType(node) {
            emitList(node, node.types, 264 /* IntersectionTypeConstituents */);
        }
        function emitParenthesizedType(node) {
            write("(");
            emit(node.type);
            write(")");
        }
        function emitThisType() {
            write("this");
        }
        function emitTypeOperator(node) {
            writeTokenText(node.operator);
            write(" ");
            emit(node.type);
        }
        function emitIndexedAccessType(node) {
            emit(node.objectType);
            write("[");
            emit(node.indexType);
            write("]");
        }
        function emitMappedType(node) {
            var emitFlags = ts.getEmitFlags(node);
            write("{");
            if (emitFlags & 1 /* SingleLine */) {
                write(" ");
            }
            else {
                writeLine();
                increaseIndent();
            }
            if (node.readonlyToken) {
                emit(node.readonlyToken);
                write(" ");
            }
            write("[");
            pipelineEmitWithNotification(3 /* MappedTypeParameter */, node.typeParameter);
            write("]");
            emitIfPresent(node.questionToken);
            write(": ");
            emit(node.type);
            write(";");
            if (emitFlags & 1 /* SingleLine */) {
                write(" ");
            }
            else {
                writeLine();
                decreaseIndent();
            }
            write("}");
        }
        function emitLiteralType(node) {
            emitExpression(node.literal);
        }
        //
        // Binding patterns
        //
        function emitObjectBindingPattern(node) {
            var elements = node.elements;
            if (elements.length === 0) {
                write("{}");
            }
            else {
                write("{");
                emitList(node, elements, 432 /* ObjectBindingPatternElements */);
                write("}");
            }
        }
        function emitArrayBindingPattern(node) {
            var elements = node.elements;
            if (elements.length === 0) {
                write("[]");
            }
            else {
                write("[");
                emitList(node, node.elements, 304 /* ArrayBindingPatternElements */);
                write("]");
            }
        }
        function emitBindingElement(node) {
            emitWithSuffix(node.propertyName, ": ");
            emitIfPresent(node.dotDotDotToken);
            emit(node.name);
            emitExpressionWithPrefix(" = ", node.initializer);
        }
        //
        // Expressions
        //
        function emitArrayLiteralExpression(node) {
            var elements = node.elements;
            var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */;
            emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine);
        }
        function emitObjectLiteralExpression(node) {
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */;
            var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */;
            emitList(node, node.properties, 263122 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitPropertyAccessExpression(node) {
            var indentBeforeDot = false;
            var indentAfterDot = false;
            if (!(ts.getEmitFlags(node) & 131072 /* NoIndentation */)) {
                var dotRangeStart = node.expression.end;
                var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1;
                var dotToken = ts.createToken(23 /* DotToken */);
                dotToken.pos = dotRangeStart;
                dotToken.end = dotRangeEnd;
                indentBeforeDot = needsIndentation(node, node.expression, dotToken);
                indentAfterDot = needsIndentation(node, dotToken, node.name);
            }
            emitExpression(node.expression);
            increaseIndentIf(indentBeforeDot);
            var shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression);
            write(shouldEmitDotDot ? ".." : ".");
            increaseIndentIf(indentAfterDot);
            emit(node.name);
            decreaseIndentIf(indentBeforeDot, indentAfterDot);
        }
        // 1..toString is a valid property access, emit a dot after the literal
        // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
        function needsDotDotForPropertyAccess(expression) {
            expression = ts.skipPartiallyEmittedExpressions(expression);
            if (ts.isNumericLiteral(expression)) {
                // check if numeric literal is a decimal literal that was originally written with a dot
                var text = getLiteralTextOfNode(expression);
                return !expression.numericLiteralFlags
                    && !ts.stringContains(text, ts.tokenToString(23 /* DotToken */));
            }
            else if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) {
                // check if constant enum value is integer
                var constantValue = ts.getConstantValue(expression);
                // isFinite handles cases when constantValue is undefined
                return typeof constantValue === "number" && isFinite(constantValue)
                    && Math.floor(constantValue) === constantValue
                    && printerOptions.removeComments;
            }
        }
        function emitElementAccessExpression(node) {
            emitExpression(node.expression);
            write("[");
            emitExpression(node.argumentExpression);
            write("]");
        }
        function emitCallExpression(node) {
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 1296 /* CallExpressionArguments */);
        }
        function emitNewExpression(node) {
            write("new ");
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 9488 /* NewExpressionArguments */);
        }
        function emitTaggedTemplateExpression(node) {
            emitExpression(node.tag);
            write(" ");
            emitExpression(node.template);
        }
        function emitTypeAssertionExpression(node) {
            write("<");
            emit(node.type);
            write(">");
            emitExpression(node.expression);
        }
        function emitParenthesizedExpression(node) {
            write("(");
            emitExpression(node.expression);
            write(")");
        }
        function emitFunctionExpression(node) {
            emitFunctionDeclarationOrExpression(node);
        }
        function emitArrowFunction(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitSignatureAndBody(node, emitArrowFunctionHead);
        }
        function emitArrowFunctionHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            emitWithPrefix(": ", node.type);
            write(" ");
            emit(node.equalsGreaterThanToken);
        }
        function emitDeleteExpression(node) {
            write("delete ");
            emitExpression(node.expression);
        }
        function emitTypeOfExpression(node) {
            write("typeof ");
            emitExpression(node.expression);
        }
        function emitVoidExpression(node) {
            write("void ");
            emitExpression(node.expression);
        }
        function emitAwaitExpression(node) {
            write("await ");
            emitExpression(node.expression);
        }
        function emitPrefixUnaryExpression(node) {
            writeTokenText(node.operator);
            if (shouldEmitWhitespaceBeforeOperand(node)) {
                write(" ");
            }
            emitExpression(node.operand);
        }
        function shouldEmitWhitespaceBeforeOperand(node) {
            // 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.
            var operand = node.operand;
            return operand.kind === 192 /* PrefixUnaryExpression */
                && ((node.operator === 37 /* PlusToken */ && (operand.operator === 37 /* PlusToken */ || operand.operator === 43 /* PlusPlusToken */))
                    || (node.operator === 38 /* MinusToken */ && (operand.operator === 38 /* MinusToken */ || operand.operator === 44 /* MinusMinusToken */)));
        }
        function emitPostfixUnaryExpression(node) {
            emitExpression(node.operand);
            writeTokenText(node.operator);
        }
        function emitBinaryExpression(node) {
            var isCommaOperator = node.operatorToken.kind !== 26 /* CommaToken */;
            var indentBeforeOperator = needsIndentation(node, node.left, node.operatorToken);
            var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right);
            emitExpression(node.left);
            increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined);
            emitLeadingCommentsOfPosition(node.operatorToken.pos);
            writeTokenNode(node.operatorToken);
            emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts
            increaseIndentIf(indentAfterOperator, " ");
            emitExpression(node.right);
            decreaseIndentIf(indentBeforeOperator, indentAfterOperator);
        }
        function emitConditionalExpression(node) {
            var indentBeforeQuestion = needsIndentation(node, node.condition, node.questionToken);
            var indentAfterQuestion = needsIndentation(node, node.questionToken, node.whenTrue);
            var indentBeforeColon = needsIndentation(node, node.whenTrue, node.colonToken);
            var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse);
            emitExpression(node.condition);
            increaseIndentIf(indentBeforeQuestion, " ");
            emit(node.questionToken);
            increaseIndentIf(indentAfterQuestion, " ");
            emitExpression(node.whenTrue);
            decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion);
            increaseIndentIf(indentBeforeColon, " ");
            emit(node.colonToken);
            increaseIndentIf(indentAfterColon, " ");
            emitExpression(node.whenFalse);
            decreaseIndentIf(indentBeforeColon, indentAfterColon);
        }
        function emitTemplateExpression(node) {
            emit(node.head);
            emitList(node, node.templateSpans, 131072 /* TemplateExpressionSpans */);
        }
        function emitYieldExpression(node) {
            write("yield");
            emit(node.asteriskToken);
            emitExpressionWithPrefix(" ", node.expression);
        }
        function emitSpreadExpression(node) {
            write("...");
            emitExpression(node.expression);
        }
        function emitClassExpression(node) {
            emitClassDeclarationOrExpression(node);
        }
        function emitExpressionWithTypeArguments(node) {
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitAsExpression(node) {
            emitExpression(node.expression);
            if (node.type) {
                write(" as ");
                emit(node.type);
            }
        }
        function emitNonNullExpression(node) {
            emitExpression(node.expression);
            write("!");
        }
        function emitMetaProperty(node) {
            writeToken(node.keywordToken, node.pos);
            write(".");
            emit(node.name);
        }
        //
        // Misc
        //
        function emitTemplateSpan(node) {
            emitExpression(node.expression);
            emit(node.literal);
        }
        //
        // Statements
        //
        function emitBlock(node) {
            writeToken(17 /* OpenBraceToken */, node.pos, /*contextNode*/ node);
            emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
            // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted
            increaseIndent();
            emitLeadingCommentsOfPosition(node.statements.end);
            decreaseIndent();
            writeToken(18 /* CloseBraceToken */, node.statements.end, /*contextNode*/ node);
        }
        function emitBlockStatements(node, forceSingleLine) {
            var format = forceSingleLine || ts.getEmitFlags(node) & 1 /* SingleLine */ ? 384 /* SingleLineBlockStatements */ : 65 /* MultiLineBlockStatements */;
            emitList(node, node.statements, format);
        }
        function emitVariableStatement(node) {
            emitModifiers(node, node.modifiers);
            emit(node.declarationList);
            write(";");
        }
        function emitEmptyStatement() {
            write(";");
        }
        function emitExpressionStatement(node) {
            emitExpression(node.expression);
            write(";");
        }
        function emitIfStatement(node) {
            var openParenPos = writeToken(90 /* IfKeyword */, node.pos, node);
            write(" ");
            writeToken(19 /* OpenParenToken */, openParenPos, node);
            emitExpression(node.expression);
            writeToken(20 /* CloseParenToken */, node.expression.end, node);
            emitEmbeddedStatement(node, node.thenStatement);
            if (node.elseStatement) {
                writeLineOrSpace(node);
                writeToken(82 /* ElseKeyword */, node.thenStatement.end, node);
                if (node.elseStatement.kind === 211 /* IfStatement */) {
                    write(" ");
                    emit(node.elseStatement);
                }
                else {
                    emitEmbeddedStatement(node, node.elseStatement);
                }
            }
        }
        function emitDoStatement(node) {
            write("do");
            emitEmbeddedStatement(node, node.statement);
            if (ts.isBlock(node.statement)) {
                write(" ");
            }
            else {
                writeLineOrSpace(node);
            }
            write("while (");
            emitExpression(node.expression);
            write(");");
        }
        function emitWhileStatement(node) {
            write("while (");
            emitExpression(node.expression);
            write(")");
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForStatement(node) {
            var openParenPos = writeToken(88 /* ForKeyword */, node.pos);
            write(" ");
            writeToken(19 /* OpenParenToken */, openParenPos, /*contextNode*/ node);
            emitForBinding(node.initializer);
            write(";");
            emitExpressionWithPrefix(" ", node.condition);
            write(";");
            emitExpressionWithPrefix(" ", node.incrementor);
            write(")");
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForInStatement(node) {
            var openParenPos = writeToken(88 /* ForKeyword */, node.pos);
            write(" ");
            writeToken(19 /* OpenParenToken */, openParenPos);
            emitForBinding(node.initializer);
            write(" in ");
            emitExpression(node.expression);
            writeToken(20 /* CloseParenToken */, node.expression.end);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForOfStatement(node) {
            var openParenPos = writeToken(88 /* ForKeyword */, node.pos);
            write(" ");
            emitWithSuffix(node.awaitModifier, " ");
            writeToken(19 /* OpenParenToken */, openParenPos);
            emitForBinding(node.initializer);
            write(" of ");
            emitExpression(node.expression);
            writeToken(20 /* CloseParenToken */, node.expression.end);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForBinding(node) {
            if (node !== undefined) {
                if (node.kind === 227 /* VariableDeclarationList */) {
                    emit(node);
                }
                else {
                    emitExpression(node);
                }
            }
        }
        function emitContinueStatement(node) {
            writeToken(77 /* ContinueKeyword */, node.pos);
            emitWithPrefix(" ", node.label);
            write(";");
        }
        function emitBreakStatement(node) {
            writeToken(72 /* BreakKeyword */, node.pos);
            emitWithPrefix(" ", node.label);
            write(";");
        }
        function emitTokenWithComment(token, pos, contextNode) {
            var node = contextNode && ts.getParseTreeNode(contextNode);
            if (node && node.kind === contextNode.kind) {
                pos = ts.skipTrivia(currentSourceFile.text, pos);
            }
            pos = writeToken(token, pos, /*contextNode*/ contextNode);
            if (node && node.kind === contextNode.kind) {
                emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true);
            }
            return pos;
        }
        function emitReturnStatement(node) {
            emitTokenWithComment(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node);
            emitExpressionWithPrefix(" ", node.expression);
            write(";");
        }
        function emitWithStatement(node) {
            write("with (");
            emitExpression(node.expression);
            write(")");
            emitEmbeddedStatement(node, node.statement);
        }
        function emitSwitchStatement(node) {
            var openParenPos = writeToken(98 /* SwitchKeyword */, node.pos);
            write(" ");
            writeToken(19 /* OpenParenToken */, openParenPos);
            emitExpression(node.expression);
            writeToken(20 /* CloseParenToken */, node.expression.end);
            write(" ");
            emit(node.caseBlock);
        }
        function emitLabeledStatement(node) {
            emit(node.label);
            write(": ");
            emit(node.statement);
        }
        function emitThrowStatement(node) {
            write("throw");
            emitExpressionWithPrefix(" ", node.expression);
            write(";");
        }
        function emitTryStatement(node) {
            write("try ");
            emit(node.tryBlock);
            if (node.catchClause) {
                writeLineOrSpace(node);
                emit(node.catchClause);
            }
            if (node.finallyBlock) {
                writeLineOrSpace(node);
                write("finally ");
                emit(node.finallyBlock);
            }
        }
        function emitDebuggerStatement(node) {
            writeToken(78 /* DebuggerKeyword */, node.pos);
            write(";");
        }
        //
        // Declarations
        //
        function emitVariableDeclaration(node) {
            emit(node.name);
            emitWithPrefix(": ", node.type);
            emitExpressionWithPrefix(" = ", node.initializer);
        }
        function emitVariableDeclarationList(node) {
            write(ts.isLet(node) ? "let " : ts.isConst(node) ? "const " : "var ");
            emitList(node, node.declarations, 272 /* VariableDeclarationList */);
        }
        function emitFunctionDeclaration(node) {
            emitFunctionDeclarationOrExpression(node);
        }
        function emitFunctionDeclarationOrExpression(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            write("function");
            emitIfPresent(node.asteriskToken);
            write(" ");
            emitIdentifierName(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitBlockCallback(_hint, body) {
            emitBlockFunctionBody(body);
        }
        function emitSignatureAndBody(node, emitSignatureHead) {
            var body = node.body;
            if (body) {
                if (ts.isBlock(body)) {
                    var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
                    if (indentedFlag) {
                        increaseIndent();
                    }
                    if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                        emitSignatureHead(node);
                        if (onEmitNode) {
                            onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
                        }
                        else {
                            emitBlockFunctionBody(body);
                        }
                    }
                    else {
                        pushNameGenerationScope();
                        emitSignatureHead(node);
                        if (onEmitNode) {
                            onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
                        }
                        else {
                            emitBlockFunctionBody(body);
                        }
                        popNameGenerationScope();
                    }
                    if (indentedFlag) {
                        decreaseIndent();
                    }
                }
                else {
                    emitSignatureHead(node);
                    write(" ");
                    emitExpression(body);
                }
            }
            else {
                emitSignatureHead(node);
                write(";");
            }
        }
        function emitSignatureHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitWithPrefix(": ", node.type);
        }
        function shouldEmitBlockFunctionBodyOnSingleLine(body) {
            // We must emit a function body as a single-line body in the following case:
            // * The body has NodeEmitFlags.SingleLine specified.
            // We must emit a function body as a multi-line body in the following cases:
            // * The body is explicitly marked as multi-line.
            // * A non-synthesized body's start and end position are on different lines.
            // * Any statement in the body starts on a new line.
            if (ts.getEmitFlags(body) & 1 /* SingleLine */) {
                return true;
            }
            if (body.multiLine) {
                return false;
            }
            if (!ts.nodeIsSynthesized(body) && !ts.rangeIsOnSingleLine(body, currentSourceFile)) {
                return false;
            }
            if (shouldWriteLeadingLineTerminator(body, body.statements, 2 /* PreserveLines */)
                || shouldWriteClosingLineTerminator(body, body.statements, 2 /* PreserveLines */)) {
                return false;
            }
            var previousStatement;
            for (var _a = 0, _b = body.statements; _a < _b.length; _a++) {
                var statement = _b[_a];
                if (shouldWriteSeparatingLineTerminator(previousStatement, statement, 2 /* PreserveLines */)) {
                    return false;
                }
                previousStatement = statement;
            }
            return true;
        }
        function emitBlockFunctionBody(body) {
            write(" {");
            increaseIndent();
            var emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body)
                ? emitBlockFunctionBodyOnSingleLine
                : emitBlockFunctionBodyWorker;
            if (emitBodyWithDetachedComments) {
                emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
            }
            else {
                emitBlockFunctionBody(body);
            }
            decreaseIndent();
            writeToken(18 /* CloseBraceToken */, body.statements.end, body);
        }
        function emitBlockFunctionBodyOnSingleLine(body) {
            emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true);
        }
        function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) {
            // Emit all the prologue directives (like "use strict").
            var statementOffset = emitPrologueDirectives(body.statements, /*startWithNewLine*/ true);
            var pos = writer.getTextPos();
            emitHelpersIndirect(body);
            if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) {
                decreaseIndent();
                emitList(body, body.statements, 384 /* SingleLineFunctionBodyStatements */);
                increaseIndent();
            }
            else {
                emitList(body, body.statements, 1 /* MultiLineFunctionBodyStatements */, statementOffset);
            }
        }
        function emitClassDeclaration(node) {
            emitClassDeclarationOrExpression(node);
        }
        function emitClassDeclarationOrExpression(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            write("class");
            emitNodeWithPrefix(" ", node.name, emitIdentifierName);
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 256 /* ClassHeritageClauses */);
            pushNameGenerationScope();
            write(" {");
            emitList(node, node.members, 65 /* ClassMembers */);
            write("}");
            popNameGenerationScope();
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitInterfaceDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            write("interface ");
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 256 /* HeritageClauses */);
            write(" {");
            emitList(node, node.members, 65 /* InterfaceMembers */);
            write("}");
        }
        function emitTypeAliasDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            write("type ");
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            write(" = ");
            emit(node.type);
            write(";");
        }
        function emitEnumDeclaration(node) {
            emitModifiers(node, node.modifiers);
            write("enum ");
            emit(node.name);
            pushNameGenerationScope();
            write(" {");
            emitList(node, node.members, 81 /* EnumMembers */);
            write("}");
            popNameGenerationScope();
        }
        function emitModuleDeclaration(node) {
            emitModifiers(node, node.modifiers);
            if (~node.flags & 512 /* GlobalAugmentation */) {
                write(node.flags & 16 /* Namespace */ ? "namespace " : "module ");
            }
            emit(node.name);
            var body = node.body;
            while (body.kind === 233 /* ModuleDeclaration */) {
                write(".");
                emit(body.name);
                body = body.body;
            }
            write(" ");
            emit(body);
        }
        function emitModuleBlock(node) {
            pushNameGenerationScope();
            write("{");
            emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
            write("}");
            popNameGenerationScope();
        }
        function emitCaseBlock(node) {
            writeToken(17 /* OpenBraceToken */, node.pos);
            emitList(node, node.clauses, 65 /* CaseBlockClauses */);
            writeToken(18 /* CloseBraceToken */, node.clauses.end);
        }
        function emitImportEqualsDeclaration(node) {
            emitModifiers(node, node.modifiers);
            write("import ");
            emit(node.name);
            write(" = ");
            emitModuleReference(node.moduleReference);
            write(";");
        }
        function emitModuleReference(node) {
            if (node.kind === 71 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitImportDeclaration(node) {
            emitModifiers(node, node.modifiers);
            write("import ");
            if (node.importClause) {
                emit(node.importClause);
                write(" from ");
            }
            emitExpression(node.moduleSpecifier);
            write(";");
        }
        function emitImportClause(node) {
            emit(node.name);
            if (node.name && node.namedBindings) {
                write(", ");
            }
            emit(node.namedBindings);
        }
        function emitNamespaceImport(node) {
            write("* as ");
            emit(node.name);
        }
        function emitNamedImports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitImportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitExportAssignment(node) {
            write(node.isExportEquals ? "export = " : "export default ");
            emitExpression(node.expression);
            write(";");
        }
        function emitExportDeclaration(node) {
            write("export ");
            if (node.exportClause) {
                emit(node.exportClause);
            }
            else {
                write("*");
            }
            if (node.moduleSpecifier) {
                write(" from ");
                emitExpression(node.moduleSpecifier);
            }
            write(";");
        }
        function emitNamespaceExportDeclaration(node) {
            write("export as namespace ");
            emit(node.name);
            write(";");
        }
        function emitNamedExports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitExportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitNamedImportsOrExports(node) {
            write("{");
            emitList(node, node.elements, 432 /* NamedImportsOrExportsElements */);
            write("}");
        }
        function emitImportOrExportSpecifier(node) {
            if (node.propertyName) {
                emit(node.propertyName);
                write(" as ");
            }
            emit(node.name);
        }
        //
        // Module references
        //
        function emitExternalModuleReference(node) {
            write("require(");
            emitExpression(node.expression);
            write(")");
        }
        //
        // JSX
        //
        function emitJsxElement(node) {
            emit(node.openingElement);
            emitList(node, node.children, 131072 /* JsxElementChildren */);
            emit(node.closingElement);
        }
        function emitJsxSelfClosingElement(node) {
            write("<");
            emitJsxTagName(node.tagName);
            write(" ");
            // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap
            if (node.attributes.properties && node.attributes.properties.length > 0) {
                emit(node.attributes);
            }
            write("/>");
        }
        function emitJsxOpeningElement(node) {
            write("<");
            emitJsxTagName(node.tagName);
            writeIfAny(node.attributes.properties, " ");
            // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
            if (node.attributes.properties && node.attributes.properties.length > 0) {
                emit(node.attributes);
            }
            write(">");
        }
        function emitJsxText(node) {
            writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true));
        }
        function emitJsxClosingElement(node) {
            write("</");
            emitJsxTagName(node.tagName);
            write(">");
        }
        function emitJsxAttributes(node) {
            emitList(node, node.properties, 131328 /* JsxElementAttributes */);
        }
        function emitJsxAttribute(node) {
            emit(node.name);
            emitWithPrefix("=", node.initializer);
        }
        function emitJsxSpreadAttribute(node) {
            write("{...");
            emitExpression(node.expression);
            write("}");
        }
        function emitJsxExpression(node) {
            if (node.expression) {
                write("{");
                emitIfPresent(node.dotDotDotToken);
                emitExpression(node.expression);
                write("}");
            }
        }
        function emitJsxTagName(node) {
            if (node.kind === 71 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        //
        // Clauses
        //
        function emitCaseClause(node) {
            write("case ");
            emitExpression(node.expression);
            write(":");
            emitCaseOrDefaultClauseStatements(node, node.statements);
        }
        function emitDefaultClause(node) {
            write("default:");
            emitCaseOrDefaultClauseStatements(node, node.statements);
        }
        function emitCaseOrDefaultClauseStatements(parentNode, statements) {
            var emitAsSingleStatement = statements.length === 1 &&
                (
                // treat synthesized nodes as located on the same line for emit purposes
                ts.nodeIsSynthesized(parentNode) ||
                    ts.nodeIsSynthesized(statements[0]) ||
                    ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
            // e.g:
            //      case 0: // Zero
            //      case 1: // One
            //      case 2: // two
            //          return "hi";
            // If there is no statements, emitNodeWithComments of the parentNode which is caseClause will take care of trailing comment.
            // So in example above, comment "// Zero" and "// One" will be emit in emitTrailingComments in emitNodeWithComments.
            // However, for "case 2", because parentNode which is caseClause has an "end" property to be end of the statements (in this case return statement)
            // comment "// two" will not be emitted in emitNodeWithComments.
            // Therefore, we have to do the check here to emit such comment.
            if (statements.length > 0) {
                // We use emitTrailingCommentsOfPosition instead of emitLeadingCommentsOfPosition because leading comments is defined as comments before the node after newline character separating it from previous line
                // Note: we can't use parentNode.end as such position includes statements.
                emitTrailingCommentsOfPosition(statements.pos);
            }
            var format = 81985 /* CaseOrDefaultClauseStatements */;
            if (emitAsSingleStatement) {
                write(" ");
                format &= ~(1 /* MultiLine */ | 64 /* Indented */);
            }
            emitList(parentNode, statements, format);
        }
        function emitHeritageClause(node) {
            write(" ");
            writeTokenText(node.token);
            write(" ");
            emitList(node, node.types, 272 /* HeritageClauseTypes */);
        }
        function emitCatchClause(node) {
            var openParenPos = writeToken(74 /* CatchKeyword */, node.pos);
            write(" ");
            if (node.variableDeclaration) {
                writeToken(19 /* OpenParenToken */, openParenPos);
                emit(node.variableDeclaration);
                writeToken(20 /* CloseParenToken */, node.variableDeclaration.end);
                write(" ");
            }
            emit(node.block);
        }
        //
        // Property assignments
        //
        function emitPropertyAssignment(node) {
            emit(node.name);
            write(": ");
            // This is to ensure that we emit comment in the following case:
            //      For example:
            //          obj = {
            //              id: /*comment1*/ ()=>void
            //          }
            // "comment1" is not considered to be leading comment for node.initializer
            // but rather a trailing comment on the previous node.
            var initializer = node.initializer;
            if (emitTrailingCommentsOfPosition && (ts.getEmitFlags(initializer) & 512 /* NoLeadingComments */) === 0) {
                var commentRange = ts.getCommentRange(initializer);
                emitTrailingCommentsOfPosition(commentRange.pos);
            }
            emitExpression(initializer);
        }
        function emitShorthandPropertyAssignment(node) {
            emit(node.name);
            if (node.objectAssignmentInitializer) {
                write(" = ");
                emitExpression(node.objectAssignmentInitializer);
            }
        }
        function emitSpreadAssignment(node) {
            if (node.expression) {
                write("...");
                emitExpression(node.expression);
            }
        }
        //
        // Enum
        //
        function emitEnumMember(node) {
            emit(node.name);
            emitExpressionWithPrefix(" = ", node.initializer);
        }
        //
        // Top-level nodes
        //
        function emitSourceFile(node) {
            writeLine();
            var statements = node.statements;
            if (emitBodyWithDetachedComments) {
                // Emit detached comment if there are no prologue directives or if the first node is synthesized.
                // The synthesized node will have no leading comment so some comments may be missed.
                var shouldEmitDetachedComment = statements.length === 0 ||
                    !ts.isPrologueDirective(statements[0]) ||
                    ts.nodeIsSynthesized(statements[0]);
                if (shouldEmitDetachedComment) {
                    emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
                    return;
                }
            }
            emitSourceFileWorker(node);
        }
        function emitSourceFileWorker(node) {
            var statements = node.statements;
            pushNameGenerationScope();
            emitHelpersIndirect(node);
            var index = ts.findIndex(statements, function (statement) { return !ts.isPrologueDirective(statement); });
            emitList(node, statements, 1 /* MultiLine */, index === -1 ? statements.length : index);
            popNameGenerationScope();
        }
        // Transformation nodes
        function emitPartiallyEmittedExpression(node) {
            emitExpression(node.expression);
        }
        function emitCommaList(node) {
            emitExpressionList(node, node.elements, 272 /* CommaListElements */);
        }
        /**
         * Emits any prologue directives at the start of a Statement list, returning the
         * number of prologue directives written to the output.
         */
        function emitPrologueDirectives(statements, startWithNewLine, seenPrologueDirectives) {
            for (var i = 0; i < statements.length; i++) {
                var statement = statements[i];
                if (ts.isPrologueDirective(statement)) {
                    var shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
                    if (shouldEmitPrologueDirective) {
                        if (startWithNewLine || i > 0) {
                            writeLine();
                        }
                        emit(statement);
                        if (seenPrologueDirectives) {
                            seenPrologueDirectives.set(statement.expression.text, true);
                        }
                    }
                }
                else {
                    // return index of the first non prologue directive
                    return i;
                }
            }
            return statements.length;
        }
        function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle)) {
                setSourceFile(sourceFileOrBundle);
                emitPrologueDirectives(sourceFileOrBundle.statements);
            }
            else {
                var seenPrologueDirectives = ts.createMap();
                for (var _a = 0, _b = sourceFileOrBundle.sourceFiles; _a < _b.length; _a++) {
                    var sourceFile = _b[_a];
                    setSourceFile(sourceFile);
                    emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
                }
            }
        }
        function emitShebangIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle)) {
                var shebang = ts.getShebang(sourceFileOrBundle.text);
                if (shebang) {
                    write(shebang);
                    writeLine();
                    return true;
                }
            }
            else {
                for (var _a = 0, _b = sourceFileOrBundle.sourceFiles; _a < _b.length; _a++) {
                    var sourceFile = _b[_a];
                    // Emit only the first encountered shebang
                    if (emitShebangIfNeeded(sourceFile)) {
                        break;
                    }
                }
            }
        }
        //
        // Helpers
        //
        function emitModifiers(node, modifiers) {
            if (modifiers && modifiers.length) {
                emitList(node, modifiers, 131328 /* Modifiers */);
                write(" ");
            }
        }
        function emitWithPrefix(prefix, node) {
            emitNodeWithPrefix(prefix, node, emit);
        }
        function emitExpressionWithPrefix(prefix, node) {
            emitNodeWithPrefix(prefix, node, emitExpression);
        }
        function emitNodeWithPrefix(prefix, node, emit) {
            if (node) {
                write(prefix);
                emit(node);
            }
        }
        function emitWithSuffix(node, suffix) {
            if (node) {
                emit(node);
                write(suffix);
            }
        }
        function emitEmbeddedStatement(parent, node) {
            if (ts.isBlock(node) || ts.getEmitFlags(parent) & 1 /* SingleLine */) {
                write(" ");
                emit(node);
            }
            else {
                writeLine();
                increaseIndent();
                emit(node);
                decreaseIndent();
            }
        }
        function emitDecorators(parentNode, decorators) {
            emitList(parentNode, decorators, 24577 /* Decorators */);
        }
        function emitTypeArguments(parentNode, typeArguments) {
            emitList(parentNode, typeArguments, 26960 /* TypeArguments */);
        }
        function emitTypeParameters(parentNode, typeParameters) {
            emitList(parentNode, typeParameters, 26960 /* TypeParameters */);
        }
        function emitParameters(parentNode, parameters) {
            emitList(parentNode, parameters, 1360 /* Parameters */);
        }
        function canEmitSimpleArrowHead(parentNode, parameters) {
            var parameter = ts.singleOrUndefined(parameters);
            return parameter
                && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
                && !(ts.isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation
                && !ts.some(parentNode.decorators) // parent may not have decorators
                && !ts.some(parentNode.modifiers) // parent may not have modifiers
                && !ts.some(parentNode.typeParameters) // parent may not have type parameters
                && !ts.some(parameter.decorators) // parameter may not have decorators
                && !ts.some(parameter.modifiers) // parameter may not have modifiers
                && !parameter.dotDotDotToken // parameter may not be rest
                && !parameter.questionToken // parameter may not be optional
                && !parameter.type // parameter may not have a type annotation
                && !parameter.initializer // parameter may not have an initializer
                && ts.isIdentifier(parameter.name); // parameter name must be identifier
        }
        function emitParametersForArrow(parentNode, parameters) {
            if (canEmitSimpleArrowHead(parentNode, parameters)) {
                emitList(parentNode, parameters, 1360 /* Parameters */ & ~1024 /* Parenthesis */);
            }
            else {
                emitParameters(parentNode, parameters);
            }
        }
        function emitParametersForIndexSignature(parentNode, parameters) {
            emitList(parentNode, parameters, 4432 /* IndexSignatureParameters */);
        }
        function emitList(parentNode, children, format, start, count) {
            emitNodeList(emit, parentNode, children, format, start, count);
        }
        function emitExpressionList(parentNode, children, format, start, count) {
            emitNodeList(emitExpression, parentNode, children, format, start, count);
        }
        function emitNodeList(emit, parentNode, children, format, start, count) {
            if (start === void 0) { start = 0; }
            if (count === void 0) { count = children ? children.length - start : 0; }
            var isUndefined = children === undefined;
            if (isUndefined && format & 8192 /* OptionalIfUndefined */) {
                return;
            }
            var isEmpty = isUndefined || start >= children.length || count === 0;
            if (isEmpty && format & 16384 /* OptionalIfEmpty */) {
                if (onBeforeEmitNodeArray) {
                    onBeforeEmitNodeArray(children);
                }
                if (onAfterEmitNodeArray) {
                    onAfterEmitNodeArray(children);
                }
                return;
            }
            if (format & 7680 /* BracketsMask */) {
                write(getOpeningBracket(format));
            }
            if (onBeforeEmitNodeArray) {
                onBeforeEmitNodeArray(children);
            }
            if (isEmpty) {
                // Write a line terminator if the parent node was multi-line
                if (format & 1 /* MultiLine */) {
                    writeLine();
                }
                else if (format & 128 /* SpaceBetweenBraces */ && !(format & 262144 /* NoSpaceIfEmpty */)) {
                    write(" ");
                }
            }
            else {
                // Write the opening line terminator or leading whitespace.
                var mayEmitInterveningComments = (format & 131072 /* NoInterveningComments */) === 0;
                var shouldEmitInterveningComments = mayEmitInterveningComments;
                if (shouldWriteLeadingLineTerminator(parentNode, children, format)) {
                    writeLine();
                    shouldEmitInterveningComments = false;
                }
                else if (format & 128 /* SpaceBetweenBraces */) {
                    write(" ");
                }
                // Increase the indent, if requested.
                if (format & 64 /* Indented */) {
                    increaseIndent();
                }
                // Emit each child.
                var previousSibling = void 0;
                var shouldDecreaseIndentAfterEmit = void 0;
                var delimiter = getDelimiter(format);
                for (var i = 0; i < count; i++) {
                    var child = children[start + i];
                    // Write the delimiter if this is not the first node.
                    if (previousSibling) {
                        // i.e
                        //      function commentedParameters(
                        //          /* Parameter a */
                        //          a
                        //          /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline
                        //          ,
                        if (delimiter && previousSibling.end !== parentNode.end) {
                            emitLeadingCommentsOfPosition(previousSibling.end);
                        }
                        write(delimiter);
                        // Write either a line terminator or whitespace to separate the elements.
                        if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) {
                            // If a synthesized node in a single-line list starts on a new
                            // line, we should increase the indent.
                            if ((format & (3 /* LinesMask */ | 64 /* Indented */)) === 0 /* SingleLine */) {
                                increaseIndent();
                                shouldDecreaseIndentAfterEmit = true;
                            }
                            writeLine();
                            shouldEmitInterveningComments = false;
                        }
                        else if (previousSibling && format & 256 /* SpaceBetweenSiblings */) {
                            write(" ");
                        }
                    }
                    // Emit this child.
                    if (shouldEmitInterveningComments) {
                        if (emitTrailingCommentsOfPosition) {
                            var commentRange = ts.getCommentRange(child);
                            emitTrailingCommentsOfPosition(commentRange.pos);
                        }
                    }
                    else {
                        shouldEmitInterveningComments = mayEmitInterveningComments;
                    }
                    emit(child);
                    if (shouldDecreaseIndentAfterEmit) {
                        decreaseIndent();
                        shouldDecreaseIndentAfterEmit = false;
                    }
                    previousSibling = child;
                }
                // Write a trailing comma, if requested.
                var hasTrailingComma = (format & 32 /* AllowTrailingComma */) && children.hasTrailingComma;
                if (format & 16 /* CommaDelimited */ && hasTrailingComma) {
                    write(",");
                }
                // Emit any trailing comment of the last element in the list
                // i.e
                //       var array = [...
                //          2
                //          /* end of element 2 */
                //       ];
                if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(ts.getEmitFlags(previousSibling) & 1024 /* NoTrailingComments */)) {
                    emitLeadingCommentsOfPosition(previousSibling.end);
                }
                // Decrease the indent, if requested.
                if (format & 64 /* Indented */) {
                    decreaseIndent();
                }
                // Write the closing line terminator or closing whitespace.
                if (shouldWriteClosingLineTerminator(parentNode, children, format)) {
                    writeLine();
                }
                else if (format & 128 /* SpaceBetweenBraces */) {
                    write(" ");
                }
            }
            if (onAfterEmitNodeArray) {
                onAfterEmitNodeArray(children);
            }
            if (format & 7680 /* BracketsMask */) {
                write(getClosingBracket(format));
            }
        }
        function write(s) {
            writer.write(s);
        }
        function writeLine() {
            writer.writeLine();
        }
        function increaseIndent() {
            writer.increaseIndent();
        }
        function decreaseIndent() {
            writer.decreaseIndent();
        }
        function writeIfAny(nodes, text) {
            if (ts.some(nodes)) {
                write(text);
            }
        }
        function writeToken(token, pos, contextNode) {
            return onEmitSourceMapOfToken
                ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
                : writeTokenText(token, pos);
        }
        function writeTokenNode(node) {
            if (onBeforeEmitToken) {
                onBeforeEmitToken(node);
            }
            write(ts.tokenToString(node.kind));
            if (onAfterEmitToken) {
                onAfterEmitToken(node);
            }
        }
        function writeTokenText(token, pos) {
            var tokenString = ts.tokenToString(token);
            write(tokenString);
            return pos < 0 ? pos : pos + tokenString.length;
        }
        function writeLineOrSpace(node) {
            if (ts.getEmitFlags(node) & 1 /* SingleLine */) {
                write(" ");
            }
            else {
                writeLine();
            }
        }
        function writeLines(text) {
            var lines = text.split(/\r\n?|\n/g);
            var indentation = guessIndentation(lines);
            for (var i = 0; i < lines.length; i++) {
                var line = indentation ? lines[i].slice(indentation) : lines[i];
                if (line.length) {
                    writeLine();
                    write(line);
                    writeLine();
                }
            }
        }
        function guessIndentation(lines) {
            var indentation;
            for (var _a = 0, lines_1 = lines; _a < lines_1.length; _a++) {
                var line = lines_1[_a];
                for (var i = 0; i < line.length && (indentation === undefined || i < indentation); i++) {
                    if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) {
                        if (indentation === undefined || i < indentation) {
                            indentation = i;
                            break;
                        }
                    }
                }
            }
            return indentation;
        }
        function increaseIndentIf(value, valueToWriteWhenNotIndenting) {
            if (value) {
                increaseIndent();
                writeLine();
            }
            else if (valueToWriteWhenNotIndenting) {
                write(valueToWriteWhenNotIndenting);
            }
        }
        // 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 shouldWriteLeadingLineTerminator(parentNode, children, format) {
            if (format & 1 /* MultiLine */) {
                return true;
            }
            if (format & 2 /* PreserveLines */) {
                if (format & 32768 /* PreferNewLine */) {
                    return true;
                }
                var firstChild = children[0];
                if (firstChild === undefined) {
                    return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile);
                }
                else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(firstChild)) {
                    return synthesizedNodeStartsOnNewLine(firstChild, format);
                }
                else {
                    return !ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile);
                }
            }
            else {
                return false;
            }
        }
        function shouldWriteSeparatingLineTerminator(previousNode, nextNode, format) {
            if (format & 1 /* MultiLine */) {
                return true;
            }
            else if (format & 2 /* PreserveLines */) {
                if (previousNode === undefined || nextNode === undefined) {
                    return false;
                }
                else if (ts.nodeIsSynthesized(previousNode) || ts.nodeIsSynthesized(nextNode)) {
                    return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format);
                }
                else {
                    return !ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile);
                }
            }
            else {
                return nextNode.startsOnNewLine;
            }
        }
        function shouldWriteClosingLineTerminator(parentNode, children, format) {
            if (format & 1 /* MultiLine */) {
                return (format & 65536 /* NoTrailingNewLine */) === 0;
            }
            else if (format & 2 /* PreserveLines */) {
                if (format & 32768 /* PreferNewLine */) {
                    return true;
                }
                var lastChild = ts.lastOrUndefined(children);
                if (lastChild === undefined) {
                    return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile);
                }
                else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(lastChild)) {
                    return synthesizedNodeStartsOnNewLine(lastChild, format);
                }
                else {
                    return !ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile);
                }
            }
            else {
                return false;
            }
        }
        function synthesizedNodeStartsOnNewLine(node, format) {
            if (ts.nodeIsSynthesized(node)) {
                var startsOnNewLine = node.startsOnNewLine;
                if (startsOnNewLine === undefined) {
                    return (format & 32768 /* PreferNewLine */) !== 0;
                }
                return startsOnNewLine;
            }
            return (format & 32768 /* PreferNewLine */) !== 0;
        }
        function needsIndentation(parent, node1, node2) {
            parent = skipSynthesizedParentheses(parent);
            node1 = skipSynthesizedParentheses(node1);
            node2 = skipSynthesizedParentheses(node2);
            // Always use a newline for synthesized code if the synthesizer desires it.
            if (node2.startsOnNewLine) {
                return true;
            }
            return !ts.nodeIsSynthesized(parent)
                && !ts.nodeIsSynthesized(node1)
                && !ts.nodeIsSynthesized(node2)
                && !ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile);
        }
        function isEmptyBlock(block) {
            return block.statements.length === 0
                && ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
        }
        function skipSynthesizedParentheses(node) {
            while (node.kind === 185 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node)) {
                node = node.expression;
            }
            return node;
        }
        function getTextOfNode(node, includeTrivia) {
            if (ts.isGeneratedIdentifier(node)) {
                return generateName(node);
            }
            else if (ts.isIdentifier(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
                return ts.idText(node);
            }
            else if (node.kind === 9 /* StringLiteral */ && node.textSourceNode) {
                return getTextOfNode(node.textSourceNode, includeTrivia);
            }
            else if (ts.isLiteralExpression(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
                return node.text;
            }
            return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
        }
        function getLiteralTextOfNode(node) {
            if (node.kind === 9 /* StringLiteral */ && node.textSourceNode) {
                var textSourceNode = node.textSourceNode;
                if (ts.isIdentifier(textSourceNode)) {
                    return ts.getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ?
                        "\"" + ts.escapeString(getTextOfNode(textSourceNode)) + "\"" :
                        "\"" + ts.escapeNonAsciiString(getTextOfNode(textSourceNode)) + "\"";
                }
                else {
                    return getLiteralTextOfNode(textSourceNode);
                }
            }
            return ts.getLiteralText(node, currentSourceFile);
        }
        /**
         * Push a new name generation scope.
         */
        function pushNameGenerationScope() {
            tempFlagsStack.push(tempFlags);
            tempFlags = 0;
        }
        /**
         * Pop the current name generation scope.
         */
        function popNameGenerationScope() {
            tempFlags = tempFlagsStack.pop();
        }
        /**
         * Generate the text for a generated identifier.
         */
        function generateName(name) {
            if (name.autoGenerateKind === 4 /* Node */) {
                // Node names generate unique names based on their original node
                // and are cached based on that node's id.
                var node = getNodeForGeneratedName(name);
                return generateNameCached(node);
            }
            else {
                // Auto, Loop, and Unique names are cached based on their unique
                // autoGenerateId.
                var autoGenerateId = name.autoGenerateId;
                return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
            }
        }
        function generateNameCached(node) {
            var nodeId = ts.getNodeId(node);
            return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node));
        }
        /**
         * Returns a value indicating whether a name is unique globally, within the current file,
         * or within the NameGenerator.
         */
        function isUniqueName(name) {
            return !(hasGlobalName && hasGlobalName(name))
                && !currentSourceFile.identifiers.has(name)
                && !generatedNames.has(name);
        }
        /**
         * Returns a value indicating whether a name is unique within a container.
         */
        function isUniqueLocalName(name, container) {
            for (var node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer) {
                if (node.locals) {
                    var local = node.locals.get(ts.escapeLeadingUnderscores(name));
                    // We conservatively include alias symbols to cover cases where they're emitted as locals
                    if (local && local.flags & (107455 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) {
                        return false;
                    }
                }
            }
            return true;
        }
        /**
         * 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 = count < 26
                        ? "_" + String.fromCharCode(97 /* a */ + count)
                        : "_" + (count - 26);
                    if (isUniqueName(name)) {
                        return name;
                    }
                }
            }
        }
        /**
         * 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)) {
                    generatedNames.set(generatedName, true);
                    return generatedName;
                }
                i++;
            }
        }
        /**
         * Generates a unique name for a ModuleDeclaration or EnumDeclaration.
         */
        function generateNameForModuleOrEnum(node) {
            var name = getTextOfNode(node.name);
            // Use module/enum name itself if it is unique, otherwise make a unique variation
            return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
        }
        /**
         * Generates a unique name for an ImportDeclaration or ExportDeclaration.
         */
        function generateNameForImportOrExportDeclaration(node) {
            var expr = ts.getExternalModuleName(node);
            var baseName = ts.isStringLiteral(expr) ?
                ts.makeIdentifierFromModuleName(expr.text) : "module";
            return makeUniqueName(baseName);
        }
        /**
         * Generates a unique name for a default export.
         */
        function generateNameForExportDefault() {
            return makeUniqueName("default");
        }
        /**
         * Generates a unique name for a class expression.
         */
        function generateNameForClassExpression() {
            return makeUniqueName("class");
        }
        function generateNameForMethodOrAccessor(node) {
            if (ts.isIdentifier(node.name)) {
                return generateNameCached(node.name);
            }
            return makeTempVariableName(0 /* Auto */);
        }
        /**
         * Generates a unique name from a node.
         */
        function generateNameForNode(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                    return makeUniqueName(getTextOfNode(node));
                case 233 /* ModuleDeclaration */:
                case 232 /* EnumDeclaration */:
                    return generateNameForModuleOrEnum(node);
                case 238 /* ImportDeclaration */:
                case 244 /* ExportDeclaration */:
                    return generateNameForImportOrExportDeclaration(node);
                case 228 /* FunctionDeclaration */:
                case 229 /* ClassDeclaration */:
                case 243 /* ExportAssignment */:
                    return generateNameForExportDefault();
                case 199 /* ClassExpression */:
                    return generateNameForClassExpression();
                case 151 /* MethodDeclaration */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                    return generateNameForMethodOrAccessor(node);
                default:
                    return makeTempVariableName(0 /* Auto */);
            }
        }
        /**
         * Generates a unique identifier for a node.
         */
        function makeName(name) {
            switch (name.autoGenerateKind) {
                case 1 /* Auto */:
                    return makeTempVariableName(0 /* Auto */);
                case 2 /* Loop */:
                    return makeTempVariableName(268435456 /* _i */);
                case 3 /* Unique */:
                    return makeUniqueName(ts.idText(name));
            }
            ts.Debug.fail("Unsupported GeneratedIdentifierKind.");
        }
        /**
         * Gets the node from which a name should be generated.
         */
        function getNodeForGeneratedName(name) {
            var autoGenerateId = name.autoGenerateId;
            var node = name;
            var original = node.original;
            while (original) {
                node = original;
                // if "node" is a different generated name (having a different
                // "autoGenerateId"), use it and stop traversing.
                if (ts.isIdentifier(node)
                    && node.autoGenerateKind === 4 /* Node */
                    && node.autoGenerateId !== autoGenerateId) {
                    break;
                }
                original = node.original;
            }
            // otherwise, return the original node for the source;
            return node;
        }
    }
    ts.createPrinter = createPrinter;
    function createDelimiterMap() {
        var delimiters = [];
        delimiters[0 /* None */] = "";
        delimiters[16 /* CommaDelimited */] = ",";
        delimiters[4 /* BarDelimited */] = " |";
        delimiters[8 /* AmpersandDelimited */] = " &";
        return delimiters;
    }
    function getDelimiter(format) {
        return delimiters[format & 28 /* DelimitersMask */];
    }
    function createBracketsMap() {
        var brackets = [];
        brackets[512 /* Braces */] = ["{", "}"];
        brackets[1024 /* Parenthesis */] = ["(", ")"];
        brackets[2048 /* AngleBrackets */] = ["<", ">"];
        brackets[4096 /* SquareBrackets */] = ["[", "]"];
        return brackets;
    }
    function getOpeningBracket(format) {
        return brackets[format & 7680 /* BracketsMask */][0];
    }
    function getClosingBracket(format) {
        return brackets[format & 7680 /* BracketsMask */][1];
    }
    // Flags enum to track count of temp variables and a few dedicated names
    var TempFlags;
    (function (TempFlags) {
        TempFlags[TempFlags["Auto"] = 0] = "Auto";
        TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
        TempFlags[TempFlags["_i"] = 268435456] = "_i";
    })(TempFlags || (TempFlags = {}));
    var ListFormat;
    (function (ListFormat) {
        ListFormat[ListFormat["None"] = 0] = "None";
        // Line separators
        ListFormat[ListFormat["SingleLine"] = 0] = "SingleLine";
        ListFormat[ListFormat["MultiLine"] = 1] = "MultiLine";
        ListFormat[ListFormat["PreserveLines"] = 2] = "PreserveLines";
        ListFormat[ListFormat["LinesMask"] = 3] = "LinesMask";
        // Delimiters
        ListFormat[ListFormat["NotDelimited"] = 0] = "NotDelimited";
        ListFormat[ListFormat["BarDelimited"] = 4] = "BarDelimited";
        ListFormat[ListFormat["AmpersandDelimited"] = 8] = "AmpersandDelimited";
        ListFormat[ListFormat["CommaDelimited"] = 16] = "CommaDelimited";
        ListFormat[ListFormat["DelimitersMask"] = 28] = "DelimitersMask";
        ListFormat[ListFormat["AllowTrailingComma"] = 32] = "AllowTrailingComma";
        // Whitespace
        ListFormat[ListFormat["Indented"] = 64] = "Indented";
        ListFormat[ListFormat["SpaceBetweenBraces"] = 128] = "SpaceBetweenBraces";
        ListFormat[ListFormat["SpaceBetweenSiblings"] = 256] = "SpaceBetweenSiblings";
        // Brackets/Braces
        ListFormat[ListFormat["Braces"] = 512] = "Braces";
        ListFormat[ListFormat["Parenthesis"] = 1024] = "Parenthesis";
        ListFormat[ListFormat["AngleBrackets"] = 2048] = "AngleBrackets";
        ListFormat[ListFormat["SquareBrackets"] = 4096] = "SquareBrackets";
        ListFormat[ListFormat["BracketsMask"] = 7680] = "BracketsMask";
        ListFormat[ListFormat["OptionalIfUndefined"] = 8192] = "OptionalIfUndefined";
        ListFormat[ListFormat["OptionalIfEmpty"] = 16384] = "OptionalIfEmpty";
        ListFormat[ListFormat["Optional"] = 24576] = "Optional";
        // Other
        ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine";
        ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine";
        ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments";
        ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty";
        ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement";
        // Precomputed Formats
        ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers";
        ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses";
        ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 448] = "SingleLineTypeLiteralMembers";
        ListFormat[ListFormat["MultiLineTypeLiteralMembers"] = 65] = "MultiLineTypeLiteralMembers";
        ListFormat[ListFormat["TupleTypeElements"] = 336] = "TupleTypeElements";
        ListFormat[ListFormat["UnionTypeConstituents"] = 260] = "UnionTypeConstituents";
        ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents";
        ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements";
        ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements";
        ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties";
        ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements";
        ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements";
        ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments";
        ListFormat[ListFormat["NewExpressionArguments"] = 9488] = "NewExpressionArguments";
        ListFormat[ListFormat["TemplateExpressionSpans"] = 131072] = "TemplateExpressionSpans";
        ListFormat[ListFormat["SingleLineBlockStatements"] = 384] = "SingleLineBlockStatements";
        ListFormat[ListFormat["MultiLineBlockStatements"] = 65] = "MultiLineBlockStatements";
        ListFormat[ListFormat["VariableDeclarationList"] = 272] = "VariableDeclarationList";
        ListFormat[ListFormat["SingleLineFunctionBodyStatements"] = 384] = "SingleLineFunctionBodyStatements";
        ListFormat[ListFormat["MultiLineFunctionBodyStatements"] = 1] = "MultiLineFunctionBodyStatements";
        ListFormat[ListFormat["ClassHeritageClauses"] = 256] = "ClassHeritageClauses";
        ListFormat[ListFormat["ClassMembers"] = 65] = "ClassMembers";
        ListFormat[ListFormat["InterfaceMembers"] = 65] = "InterfaceMembers";
        ListFormat[ListFormat["EnumMembers"] = 81] = "EnumMembers";
        ListFormat[ListFormat["CaseBlockClauses"] = 65] = "CaseBlockClauses";
        ListFormat[ListFormat["NamedImportsOrExportsElements"] = 432] = "NamedImportsOrExportsElements";
        ListFormat[ListFormat["JsxElementChildren"] = 131072] = "JsxElementChildren";
        ListFormat[ListFormat["JsxElementAttributes"] = 131328] = "JsxElementAttributes";
        ListFormat[ListFormat["CaseOrDefaultClauseStatements"] = 81985] = "CaseOrDefaultClauseStatements";
        ListFormat[ListFormat["HeritageClauseTypes"] = 272] = "HeritageClauseTypes";
        ListFormat[ListFormat["SourceFileStatements"] = 65537] = "SourceFileStatements";
        ListFormat[ListFormat["Decorators"] = 24577] = "Decorators";
        ListFormat[ListFormat["TypeArguments"] = 26960] = "TypeArguments";
        ListFormat[ListFormat["TypeParameters"] = 26960] = "TypeParameters";
        ListFormat[ListFormat["Parameters"] = 1360] = "Parameters";
        ListFormat[ListFormat["IndexSignatureParameters"] = 4432] = "IndexSignatureParameters";
    })(ListFormat || (ListFormat = {}));
})(ts || (ts = {}));
/// <reference path="program.ts" />
/* @internal */
var ts;
(function (ts) {
    function getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers) {
        var outputFiles = [];
        var emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
        return { outputFiles: outputFiles, emitSkipped: emitResult.emitSkipped };
        function writeFile(fileName, text, writeByteOrderMark) {
            outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: text });
        }
    }
    ts.getFileEmitOutput = getFileEmitOutput;
    function createBuilder(options) {
        var isModuleEmit;
        var fileInfos = ts.createMap();
        var semanticDiagnosticsPerFile = ts.createMap();
        /** The map has key by source file's path that has been changed */
        var changedFilesSet = ts.createMap();
        var hasShapeChanged = ts.createMap();
        var allFilesExcludingDefaultLibraryFile;
        var emitHandler;
        return {
            updateProgram: updateProgram,
            getFilesAffectedBy: getFilesAffectedBy,
            emitChangedFiles: emitChangedFiles,
            getSemanticDiagnostics: getSemanticDiagnostics,
            clear: clear
        };
        function createProgramGraph(program) {
            var currentIsModuleEmit = program.getCompilerOptions().module !== ts.ModuleKind.None;
            if (isModuleEmit !== currentIsModuleEmit) {
                isModuleEmit = currentIsModuleEmit;
                emitHandler = isModuleEmit ? getModuleEmitHandler() : getNonModuleEmitHandler();
                fileInfos.clear();
                semanticDiagnosticsPerFile.clear();
            }
            hasShapeChanged.clear();
            allFilesExcludingDefaultLibraryFile = undefined;
            ts.mutateMap(fileInfos, ts.arrayToMap(program.getSourceFiles(), function (sourceFile) { return sourceFile.path; }), {
                // Add new file info
                createNewValue: function (_path, sourceFile) { return addNewFileInfo(program, sourceFile); },
                // Remove existing file info
                onDeleteValue: removeExistingFileInfo,
                // We will update in place instead of deleting existing value and adding new one
                onExistingValue: function (existingInfo, sourceFile) { return updateExistingFileInfo(program, existingInfo, sourceFile); }
            });
        }
        function registerChangedFile(path) {
            changedFilesSet.set(path, true);
            // All changed files need to re-evaluate its semantic diagnostics
            semanticDiagnosticsPerFile.delete(path);
        }
        function addNewFileInfo(program, sourceFile) {
            registerChangedFile(sourceFile.path);
            emitHandler.onAddSourceFile(program, sourceFile);
            return { version: sourceFile.version, signature: undefined };
        }
        function removeExistingFileInfo(_existingFileInfo, path) {
            // Since we dont need to track removed file as changed file
            // We can just remove its diagnostics
            changedFilesSet.delete(path);
            semanticDiagnosticsPerFile.delete(path);
            emitHandler.onRemoveSourceFile(path);
        }
        function updateExistingFileInfo(program, existingInfo, sourceFile) {
            if (existingInfo.version !== sourceFile.version) {
                registerChangedFile(sourceFile.path);
                existingInfo.version = sourceFile.version;
                emitHandler.onUpdateSourceFile(program, sourceFile);
            }
            else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) {
                registerChangedFile(sourceFile.path);
            }
        }
        function ensureProgramGraph(program) {
            if (!emitHandler) {
                createProgramGraph(program);
            }
        }
        function updateProgram(newProgram) {
            if (emitHandler) {
                createProgramGraph(newProgram);
            }
        }
        function getFilesAffectedBy(program, path) {
            ensureProgramGraph(program);
            var sourceFile = program.getSourceFileByPath(path);
            if (!sourceFile) {
                return ts.emptyArray;
            }
            if (!updateShapeSignature(program, sourceFile)) {
                return [sourceFile];
            }
            return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile);
        }
        function emitChangedFiles(program, writeFileCallback) {
            ensureProgramGraph(program);
            var compilerOptions = program.getCompilerOptions();
            if (!changedFilesSet.size) {
                return ts.emptyArray;
            }
            // With --out or --outFile all outputs go into single file, do it only once
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(semanticDiagnosticsPerFile.size === 0);
                changedFilesSet.clear();
                return [program.emit(/*targetSourceFile*/ undefined, writeFileCallback)];
            }
            var seenFiles = ts.createMap();
            var result;
            changedFilesSet.forEach(function (_true, path) {
                // Get the affected Files by this program
                var affectedFiles = getFilesAffectedBy(program, path);
                affectedFiles.forEach(function (affectedFile) {
                    // Affected files shouldnt have cached diagnostics
                    semanticDiagnosticsPerFile.delete(affectedFile.path);
                    if (!seenFiles.has(affectedFile.path)) {
                        seenFiles.set(affectedFile.path, true);
                        // Emit the affected file
                        (result || (result = [])).push(program.emit(affectedFile, writeFileCallback));
                    }
                });
            });
            changedFilesSet.clear();
            return result || ts.emptyArray;
        }
        function getSemanticDiagnostics(program, cancellationToken) {
            ensureProgramGraph(program);
            ts.Debug.assert(changedFilesSet.size === 0);
            var compilerOptions = program.getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(semanticDiagnosticsPerFile.size === 0);
                // We dont need to cache the diagnostics just return them from program
                return program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken);
            }
            var diagnostics;
            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken));
            }
            return diagnostics || ts.emptyArray;
        }
        function getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken) {
            var path = sourceFile.path;
            var cachedDiagnostics = semanticDiagnosticsPerFile.get(path);
            // Report the semantic diagnostics from the cache if we already have those diagnostics present
            if (cachedDiagnostics) {
                return cachedDiagnostics;
            }
            // Diagnostics werent cached, get them from program, and cache the result
            var diagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken);
            semanticDiagnosticsPerFile.set(path, diagnostics);
            return diagnostics;
        }
        function clear() {
            isModuleEmit = undefined;
            emitHandler = undefined;
            fileInfos.clear();
            semanticDiagnosticsPerFile.clear();
            changedFilesSet.clear();
            hasShapeChanged.clear();
        }
        /**
         * For script files that contains only ambient external modules, although they are not actually external module files,
         * they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore,
         * there are no point to rebuild all script files if these special files have changed. However, if any statement
         * in the file is not ambient external module, we treat it as a regular script file.
         */
        function containsOnlyAmbientModules(sourceFile) {
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (!ts.isModuleWithStringLiteralName(statement)) {
                    return false;
                }
            }
            return true;
        }
        /**
         * @return {boolean} indicates if the shape signature has changed since last update.
         */
        function updateShapeSignature(program, sourceFile) {
            ts.Debug.assert(!!sourceFile);
            // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
            if (hasShapeChanged.has(sourceFile.path)) {
                return false;
            }
            hasShapeChanged.set(sourceFile.path, true);
            var info = fileInfos.get(sourceFile.path);
            ts.Debug.assert(!!info);
            var prevSignature = info.signature;
            var latestSignature;
            if (sourceFile.isDeclarationFile) {
                latestSignature = sourceFile.version;
                info.signature = latestSignature;
            }
            else {
                var emitOutput = getFileEmitOutput(program, sourceFile, /*emitOnlyDtsFiles*/ true);
                if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
                    latestSignature = options.computeHash(emitOutput.outputFiles[0].text);
                    info.signature = latestSignature;
                }
                else {
                    latestSignature = prevSignature;
                }
            }
            return !prevSignature || latestSignature !== prevSignature;
        }
        /**
         * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
         */
        function getReferencedFiles(program, sourceFile) {
            var referencedFiles;
            // We need to use a set here since the code can contain the same import twice,
            // but that will only be one dependency.
            // To avoid invernal conversion, the key of the referencedFiles map must be of type Path
            if (sourceFile.imports && sourceFile.imports.length > 0) {
                var checker = program.getTypeChecker();
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var importName = _a[_i];
                    var symbol = checker.getSymbolAtLocation(importName);
                    if (symbol && symbol.declarations && symbol.declarations[0]) {
                        var declarationSourceFile = ts.getSourceFileOfNode(symbol.declarations[0]);
                        if (declarationSourceFile) {
                            addReferencedFile(declarationSourceFile.path);
                        }
                    }
                }
            }
            var sourceFileDirectory = ts.getDirectoryPath(sourceFile.path);
            // Handle triple slash references
            if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
                for (var _b = 0, _c = sourceFile.referencedFiles; _b < _c.length; _b++) {
                    var referencedFile = _c[_b];
                    var referencedPath = ts.toPath(referencedFile.fileName, sourceFileDirectory, options.getCanonicalFileName);
                    addReferencedFile(referencedPath);
                }
            }
            // Handle type reference directives
            if (sourceFile.resolvedTypeReferenceDirectiveNames) {
                sourceFile.resolvedTypeReferenceDirectiveNames.forEach(function (resolvedTypeReferenceDirective) {
                    if (!resolvedTypeReferenceDirective) {
                        return;
                    }
                    var fileName = resolvedTypeReferenceDirective.resolvedFileName;
                    var typeFilePath = ts.toPath(fileName, sourceFileDirectory, options.getCanonicalFileName);
                    addReferencedFile(typeFilePath);
                });
            }
            return referencedFiles;
            function addReferencedFile(referencedPath) {
                if (!referencedFiles) {
                    referencedFiles = ts.createMap();
                }
                referencedFiles.set(referencedPath, true);
            }
        }
        /**
         * Gets all files of the program excluding the default library file
         */
        function getAllFilesExcludingDefaultLibraryFile(program, firstSourceFile) {
            // Use cached result
            if (allFilesExcludingDefaultLibraryFile) {
                return allFilesExcludingDefaultLibraryFile;
            }
            var result;
            addSourceFile(firstSourceFile);
            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                if (sourceFile !== firstSourceFile) {
                    addSourceFile(sourceFile);
                }
            }
            allFilesExcludingDefaultLibraryFile = result || ts.emptyArray;
            return allFilesExcludingDefaultLibraryFile;
            function addSourceFile(sourceFile) {
                if (!program.isSourceFileDefaultLibrary(sourceFile)) {
                    (result || (result = [])).push(sourceFile);
                }
            }
        }
        function getNonModuleEmitHandler() {
            return {
                onAddSourceFile: ts.noop,
                onRemoveSourceFile: ts.noop,
                onUpdateSourceFile: ts.noop,
                onUpdateSourceFileWithSameVersion: ts.returnFalse,
                getFilesAffectedByUpdatedShape: getFilesAffectedByUpdatedShape
            };
            function getFilesAffectedByUpdatedShape(program, sourceFile) {
                var options = program.getCompilerOptions();
                // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
                // so returning the file itself is good enough.
                if (options && (options.out || options.outFile)) {
                    return [sourceFile];
                }
                return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
            }
        }
        function getModuleEmitHandler() {
            var references = ts.createMap();
            return {
                onAddSourceFile: setReferences,
                onRemoveSourceFile: onRemoveSourceFile,
                onUpdateSourceFile: updateReferences,
                onUpdateSourceFileWithSameVersion: updateReferencesTrackingChangedReferences,
                getFilesAffectedByUpdatedShape: getFilesAffectedByUpdatedShape
            };
            function setReferences(program, sourceFile) {
                var newReferences = getReferencedFiles(program, sourceFile);
                if (newReferences) {
                    references.set(sourceFile.path, newReferences);
                }
            }
            function updateReferences(program, sourceFile) {
                var newReferences = getReferencedFiles(program, sourceFile);
                if (newReferences) {
                    references.set(sourceFile.path, newReferences);
                }
                else {
                    references.delete(sourceFile.path);
                }
            }
            function updateReferencesTrackingChangedReferences(program, sourceFile) {
                var newReferences = getReferencedFiles(program, sourceFile);
                if (!newReferences) {
                    // Changed if we had references
                    return references.delete(sourceFile.path);
                }
                var oldReferences = references.get(sourceFile.path);
                references.set(sourceFile.path, newReferences);
                if (!oldReferences || oldReferences.size !== newReferences.size) {
                    return true;
                }
                // If there are any new references that werent present previously there is change
                return ts.forEachEntry(newReferences, function (_true, referencedPath) { return !oldReferences.delete(referencedPath); }) ||
                    // Otherwise its changed if there are more references previously than now
                    !!oldReferences.size;
            }
            function onRemoveSourceFile(removedFilePath) {
                // Remove existing references
                references.forEach(function (referencesInFile, filePath) {
                    if (referencesInFile.has(removedFilePath)) {
                        // add files referencing the removedFilePath, as changed files too
                        var referencedByInfo = fileInfos.get(filePath);
                        if (referencedByInfo) {
                            registerChangedFile(filePath);
                        }
                    }
                });
                // Delete the entry for the removed file path
                references.delete(removedFilePath);
            }
            function getReferencedByPaths(referencedFilePath) {
                return ts.mapDefinedIter(references.entries(), function (_a) {
                    var filePath = _a[0], referencesInFile = _a[1];
                    return referencesInFile.has(referencedFilePath) ? filePath : undefined;
                });
            }
            function getFilesAffectedByUpdatedShape(program, sourceFile) {
                if (!ts.isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile)) {
                    return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
                }
                var compilerOptions = program.getCompilerOptions();
                if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
                    return [sourceFile];
                }
                // Now we need to if each file in the referencedBy list has a shape change as well.
                // Because if so, its own referencedBy files need to be saved as well to make the
                // emitting result consistent with files on disk.
                var seenFileNamesMap = ts.createMap();
                // Start with the paths this file was referenced by
                var path = sourceFile.path;
                seenFileNamesMap.set(path, sourceFile);
                var queue = getReferencedByPaths(path);
                while (queue.length > 0) {
                    var currentPath = queue.pop();
                    if (!seenFileNamesMap.has(currentPath)) {
                        var currentSourceFile = program.getSourceFileByPath(currentPath);
                        seenFileNamesMap.set(currentPath, currentSourceFile);
                        if (currentSourceFile && updateShapeSignature(program, currentSourceFile)) {
                            queue.push.apply(queue, getReferencedByPaths(currentPath));
                        }
                    }
                }
                // Return array of values that needs emit
                return ts.flatMapIter(seenFileNamesMap.values(), function (value) { return value; });
            }
        }
    }
    ts.createBuilder = createBuilder;
})(ts || (ts = {}));
/// <reference path="sys.ts" />
/// <reference path="emitter.ts" />
/// <reference path="core.ts" />
/// <reference path="builder.ts" />
var ts;
(function (ts) {
    var ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
    function findConfigFile(searchPath, fileExists, configName) {
        if (configName === void 0) { configName = "tsconfig.json"; }
        while (true) {
            var fileName = ts.combinePaths(searchPath, configName);
            if (fileExists(fileName)) {
                return fileName;
            }
            var parentPath = ts.getDirectoryPath(searchPath);
            if (parentPath === searchPath) {
                break;
            }
            searchPath = parentPath;
        }
        return undefined;
    }
    ts.findConfigFile = findConfigFile;
    function resolveTripleslashReference(moduleName, containingFile) {
        var basePath = ts.getDirectoryPath(containingFile);
        var referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName);
        return ts.normalizePath(referencedFileName);
    }
    ts.resolveTripleslashReference = resolveTripleslashReference;
    /* @internal */
    function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) {
        var commonPathComponents;
        var failed = ts.forEach(fileNames, function (sourceFile) {
            // Each file contributes into common source file path
            var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory);
            sourcePathComponents.pop(); // The base file name is not part of the common directory path
            if (!commonPathComponents) {
                // first file
                commonPathComponents = sourcePathComponents;
                return;
            }
            var n = Math.min(commonPathComponents.length, sourcePathComponents.length);
            for (var i = 0; i < n; i++) {
                if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
                    if (i === 0) {
                        // Failed to find any common path component
                        return true;
                    }
                    // New common path found that is 0 -> i-1
                    commonPathComponents.length = i;
                    break;
                }
            }
            // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents
            if (sourcePathComponents.length < commonPathComponents.length) {
                commonPathComponents.length = sourcePathComponents.length;
            }
        });
        // A common path can not be found when paths span multiple drives on windows, for example
        if (failed) {
            return "";
        }
        if (!commonPathComponents) {
            return currentDirectory;
        }
        return ts.getNormalizedPathFromPathComponents(commonPathComponents);
    }
    ts.computeCommonSourceDirectoryOfFilenames = computeCommonSourceDirectoryOfFilenames;
    function createCompilerHost(options, setParentNodes) {
        var existingDirectories = ts.createMap();
        function getCanonicalFileName(fileName) {
            // if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
            // otherwise use toLowerCase as a canonical form.
            return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
        }
        function getSourceFile(fileName, languageVersion, onError) {
            var text;
            try {
                ts.performance.mark("beforeIORead");
                text = ts.sys.readFile(fileName, options.charset);
                ts.performance.mark("afterIORead");
                ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
                text = "";
            }
            return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
        }
        function directoryExists(directoryPath) {
            if (existingDirectories.has(directoryPath)) {
                return true;
            }
            if (ts.sys.directoryExists(directoryPath)) {
                existingDirectories.set(directoryPath, true);
                return true;
            }
            return false;
        }
        function ensureDirectoriesExist(directoryPath) {
            if (directoryPath.length > ts.getRootLength(directoryPath) && !directoryExists(directoryPath)) {
                var parentDirectory = ts.getDirectoryPath(directoryPath);
                ensureDirectoriesExist(parentDirectory);
                ts.sys.createDirectory(directoryPath);
            }
        }
        var outputFingerprints;
        function writeFileIfUpdated(fileName, data, writeByteOrderMark) {
            if (!outputFingerprints) {
                outputFingerprints = ts.createMap();
            }
            var hash = ts.sys.createHash(data);
            var mtimeBefore = ts.sys.getModifiedTime(fileName);
            if (mtimeBefore) {
                var fingerprint = outputFingerprints.get(fileName);
                // If output has not been changed, and the file has no external modification
                if (fingerprint &&
                    fingerprint.byteOrderMark === writeByteOrderMark &&
                    fingerprint.hash === hash &&
                    fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
                    return;
                }
            }
            ts.sys.writeFile(fileName, data, writeByteOrderMark);
            var mtimeAfter = ts.sys.getModifiedTime(fileName);
            outputFingerprints.set(fileName, {
                hash: hash,
                byteOrderMark: writeByteOrderMark,
                mtime: mtimeAfter
            });
        }
        function writeFile(fileName, data, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(fileName)));
                if (ts.isWatchSet(options) && ts.sys.createHash && ts.sys.getModifiedTime) {
                    writeFileIfUpdated(fileName, data, writeByteOrderMark);
                }
                else {
                    ts.sys.writeFile(fileName, data, writeByteOrderMark);
                }
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
        function getDefaultLibLocation() {
            return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath()));
        }
        var newLine = ts.getNewLineCharacter(options);
        var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); });
        return {
            getSourceFile: getSourceFile,
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return ts.sys.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return ts.sys.useCaseSensitiveFileNames; },
            getCanonicalFileName: getCanonicalFileName,
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return ts.sys.fileExists(fileName); },
            readFile: function (fileName) { return ts.sys.readFile(fileName); },
            trace: function (s) { return ts.sys.write(s + newLine); },
            directoryExists: function (directoryName) { return ts.sys.directoryExists(directoryName); },
            getEnvironmentVariable: function (name) { return ts.sys.getEnvironmentVariable ? ts.sys.getEnvironmentVariable(name) : ""; },
            getDirectories: function (path) { return ts.sys.getDirectories(path); },
            realpath: realpath
        };
    }
    ts.createCompilerHost = createCompilerHost;
    function getPreEmitDiagnostics(program, sourceFile, cancellationToken) {
        var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
        if (program.getCompilerOptions().declaration) {
            ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
        }
        return ts.sortAndDeduplicateDiagnostics(diagnostics);
    }
    ts.getPreEmitDiagnostics = getPreEmitDiagnostics;
    function formatDiagnostics(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) {
            var diagnostic = diagnostics_1[_i];
            output += formatDiagnostic(diagnostic, host);
        }
        return output;
    }
    ts.formatDiagnostics = formatDiagnostics;
    function formatDiagnostic(diagnostic, host) {
        var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
        var errorMessage = category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine();
        if (diagnostic.file) {
            var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character;
            var fileName = diagnostic.file.fileName;
            var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); });
            return relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): " + errorMessage;
        }
        return errorMessage;
    }
    ts.formatDiagnostic = formatDiagnostic;
    var redForegroundEscapeSequence = "\u001b[91m";
    var yellowForegroundEscapeSequence = "\u001b[93m";
    var blueForegroundEscapeSequence = "\u001b[93m";
    var gutterStyleSequence = "\u001b[30;47m";
    var gutterSeparator = " ";
    var resetEscapeSequence = "\u001b[0m";
    var ellipsis = "...";
    function getCategoryFormat(category) {
        switch (category) {
            case ts.DiagnosticCategory.Warning: return yellowForegroundEscapeSequence;
            case ts.DiagnosticCategory.Error: return redForegroundEscapeSequence;
            case ts.DiagnosticCategory.Message: return blueForegroundEscapeSequence;
        }
    }
    function formatAndReset(text, formatStyle) {
        return formatStyle + text + resetEscapeSequence;
    }
    function padLeft(s, length) {
        while (s.length < length) {
            s = " " + s;
        }
        return s;
    }
    function formatDiagnosticsWithColorAndContext(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) {
            var diagnostic = diagnostics_2[_i];
            var context = "";
            if (diagnostic.file) {
                var start = diagnostic.start, length_5 = diagnostic.length, file = diagnostic.file;
                var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character;
                var _b = ts.getLineAndCharacterOfPosition(file, start + length_5), lastLine = _b.line, lastLineChar = _b.character;
                var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line;
                var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName;
                var hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
                var gutterWidth = (lastLine + 1 + "").length;
                if (hasMoreThanFiveLines) {
                    gutterWidth = Math.max(ellipsis.length, gutterWidth);
                }
                context += host.getNewLine();
                for (var i = firstLine; i <= lastLine; i++) {
                    // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
                    // so we'll skip ahead to the second-to-last line.
                    if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
                        context += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
                        i = lastLine - 1;
                    }
                    var lineStart = ts.getPositionOfLineAndCharacter(file, i, 0);
                    var lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
                    var lineContent = file.text.slice(lineStart, lineEnd);
                    lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
                    lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
                    // Output the gutter and the actual contents of the line.
                    context += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
                    context += lineContent + host.getNewLine();
                    // Output the gutter and the error span for the line using tildes.
                    context += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
                    context += redForegroundEscapeSequence;
                    if (i === firstLine) {
                        // If we're on the last line, then limit it to the last character of the last line.
                        // Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
                        var lastCharForLine = i === lastLine ? lastLineChar : undefined;
                        context += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
                        context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
                    }
                    else if (i === lastLine) {
                        context += lineContent.slice(0, lastLineChar).replace(/./g, "~");
                    }
                    else {
                        // Squiggle the entire line.
                        context += lineContent.replace(/./g, "~");
                    }
                    context += resetEscapeSequence;
                }
                output += host.getNewLine();
                output += relativeFileName + "(" + (firstLine + 1) + "," + (firstLineChar + 1) + "): ";
            }
            var categoryColor = getCategoryFormat(diagnostic.category);
            var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
            output += formatAndReset(category, categoryColor) + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
            if (diagnostic.file) {
                output += host.getNewLine();
                output += context;
            }
            output += host.getNewLine();
        }
        return output;
    }
    ts.formatDiagnosticsWithColorAndContext = formatDiagnosticsWithColorAndContext;
    function flattenDiagnosticMessageText(messageText, newLine) {
        if (ts.isString(messageText)) {
            return messageText;
        }
        else {
            var diagnosticChain = messageText;
            var result = "";
            var indent = 0;
            while (diagnosticChain) {
                if (indent) {
                    result += newLine;
                    for (var i = 0; i < indent; i++) {
                        result += "  ";
                    }
                }
                result += diagnosticChain.messageText;
                indent++;
                diagnosticChain = diagnosticChain.next;
            }
            return result;
        }
    }
    ts.flattenDiagnosticMessageText = flattenDiagnosticMessageText;
    function loadWithLocalCache(names, containingFile, loader) {
        if (names.length === 0) {
            return [];
        }
        var resolutions = [];
        var cache = ts.createMap();
        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
            var name = names_1[_i];
            var result = void 0;
            if (cache.has(name)) {
                result = cache.get(name);
            }
            else {
                cache.set(name, result = loader(name, containingFile));
            }
            resolutions.push(result);
        }
        return resolutions;
    }
    /**
     * Determines if program structure is upto date or needs to be recreated
     */
    /* @internal */
    function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames) {
        // If we haven't create a program yet or has changed automatic type directives, then it is not up-to-date
        if (!program || hasChangedAutomaticTypeDirectiveNames) {
            return false;
        }
        // If number of files in the program do not match, it is not up-to-date
        if (program.getRootFileNames().length !== rootFileNames.length) {
            return false;
        }
        // If any file is not up-to-date, then the whole program is not up-to-date
        if (program.getSourceFiles().some(sourceFileNotUptoDate)) {
            return false;
        }
        // If any of the missing file paths are now created
        if (program.getMissingFilePaths().some(fileExists)) {
            return false;
        }
        var currentOptions = program.getCompilerOptions();
        // If the compilation settings do no match, then the program is not up-to-date
        if (!ts.compareDataObjects(currentOptions, newOptions)) {
            return false;
        }
        // If everything matches but the text of config file is changed,
        // error locations can change for program options, so update the program
        if (currentOptions.configFile && newOptions.configFile) {
            return currentOptions.configFile.text === newOptions.configFile.text;
        }
        return true;
        function sourceFileNotUptoDate(sourceFile) {
            return sourceFile.version !== getSourceVersion(sourceFile.path) ||
                hasInvalidatedResolution(sourceFile.path);
        }
    }
    ts.isProgramUptoDate = isProgramUptoDate;
    /**
     * Determined if source file needs to be re-created even if its text hasnt changed
     */
    function shouldProgramCreateNewSourceFiles(program, newOptions) {
        // If any of these options change, we cant reuse old source file even if version match
        // The change in options like these could result in change in syntax tree change
        var oldOptions = program && program.getCompilerOptions();
        return oldOptions && (oldOptions.target !== newOptions.target ||
            oldOptions.module !== newOptions.module ||
            oldOptions.moduleResolution !== newOptions.moduleResolution ||
            oldOptions.noResolve !== newOptions.noResolve ||
            oldOptions.jsx !== newOptions.jsx ||
            oldOptions.allowJs !== newOptions.allowJs ||
            oldOptions.disableSizeLimit !== newOptions.disableSizeLimit ||
            oldOptions.baseUrl !== newOptions.baseUrl ||
            !ts.equalOwnProperties(oldOptions.paths, newOptions.paths));
    }
    /**
     * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'
     * that represent a compilation unit.
     *
     * Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and
     * triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in.
     *
     * @param rootNames - A set of root files.
     * @param options - The compiler options which should be used.
     * @param host - The host interacts with the underlying file system.
     * @param oldProgram - Reuses an old program structure.
     * @returns A 'Program' object.
     */
    function createProgram(rootNames, options, host, oldProgram) {
        var program;
        var files = [];
        var commonSourceDirectory;
        var diagnosticsProducingTypeChecker;
        var noDiagnosticsTypeChecker;
        var classifiableNames;
        var modifiedFilePaths;
        var cachedSemanticDiagnosticsForFile = {};
        var cachedDeclarationDiagnosticsForFile = {};
        var resolvedTypeReferenceDirectives = ts.createMap();
        var fileProcessingDiagnostics = ts.createDiagnosticCollection();
        // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
        // This works as imported modules are discovered recursively in a depth first manner, specifically:
        // - For each root file, findSourceFile is called.
        // - This calls processImportedModules for each module imported in the source file.
        // - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
        // As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
        // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
        var maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
        var currentNodeModulesDepth = 0;
        // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
        // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed.
        var modulesWithElidedImports = ts.createMap();
        // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
        var sourceFilesFoundSearchingNodeModules = ts.createMap();
        ts.performance.mark("beforeProgram");
        host = host || createCompilerHost(options);
        var skipDefaultLib = options.noLib;
        var getDefaultLibraryFileName = ts.memoize(function () { return host.getDefaultLibFileName(options); });
        var defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName());
        var programDiagnostics = ts.createDiagnosticCollection();
        var currentDirectory = host.getCurrentDirectory();
        var supportedExtensions = ts.getSupportedExtensions(options);
        // Map storing if there is emit blocking diagnostics for given input
        var hasEmitBlockingDiagnostics = ts.createMap();
        var _compilerOptionsObjectLiteralSyntax;
        var moduleResolutionCache;
        var resolveModuleNamesWorker;
        var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
        if (host.resolveModuleNames) {
            resolveModuleNamesWorker = function (moduleNames, containingFile, reusedNames) { return host.resolveModuleNames(checkAllDefined(moduleNames), containingFile, reusedNames).map(function (resolved) {
                // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
                if (!resolved || resolved.extension !== undefined) {
                    return resolved;
                }
                var withExtension = ts.clone(resolved);
                withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName);
                return withExtension;
            }); };
        }
        else {
            moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, function (x) { return host.getCanonicalFileName(x); });
            var loader_1 = function (moduleName, containingFile) { return ts.resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule; };
            resolveModuleNamesWorker = function (moduleNames, containingFile) { return loadWithLocalCache(checkAllDefined(moduleNames), containingFile, loader_1); };
        }
        var resolveTypeReferenceDirectiveNamesWorker;
        if (host.resolveTypeReferenceDirectives) {
            resolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile) { return host.resolveTypeReferenceDirectives(checkAllDefined(typeDirectiveNames), containingFile); };
        }
        else {
            var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; };
            resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); };
        }
        // Map from a stringified PackageId to the source file with that id.
        // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile).
        // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around.
        var packageIdToSourceFile = ts.createMap();
        // Maps from a SourceFile's `.path` to the name of the package it was imported with.
        var sourceFileToPackageName = ts.createMap();
        // See `sourceFileIsRedirectedTo`.
        var redirectTargetsSet = ts.createMap();
        var filesByName = ts.createMap();
        var missingFilePaths;
        // stores 'filename -> file association' ignoring case
        // used to track cases when two file names differ only in casing
        var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined;
        var shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
        var structuralIsReused = tryReuseStructureFromOldProgram();
        if (structuralIsReused !== 2 /* Completely */) {
            ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); });
            // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
            var typeReferences = ts.getAutomaticTypeDirectiveNames(options, host);
            if (typeReferences.length) {
                // This containingFilename needs to match with the one used in managed-side
                var containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
                var containingFilename = ts.combinePaths(containingDirectory, "__inferred type names__.ts");
                var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
                for (var i = 0; i < typeReferences.length; i++) {
                    processTypeReferenceDirective(typeReferences[i], resolutions[i]);
                }
            }
            // Do not process the default library if:
            //  - The '--noLib' flag is used.
            //  - A 'no-default-lib' reference comment is encountered in
            //      processing the root files.
            if (!skipDefaultLib) {
                // If '--lib' is not specified, include default library file according to '--target'
                // otherwise, using options specified in '--lib' instead of '--target' default library file
                if (!options.lib) {
                    processRootFile(getDefaultLibraryFileName(), /*isDefaultLib*/ true);
                }
                else {
                    ts.forEach(options.lib, function (libFileName) {
                        processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true);
                    });
                }
            }
            missingFilePaths = ts.arrayFrom(filesByName.keys(), function (p) { return p; }).filter(function (p) { return !filesByName.get(p); });
        }
        ts.Debug.assert(!!missingFilePaths);
        // unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
        moduleResolutionCache = undefined;
        // Release any files we have acquired in the old program but are
        // not part of the new program.
        if (oldProgram && host.onReleaseOldSourceFile) {
            var oldSourceFiles = oldProgram.getSourceFiles();
            for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) {
                var oldSourceFile = oldSourceFiles_1[_i];
                if (!getSourceFile(oldSourceFile.path) || shouldCreateNewSourceFile) {
                    host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions());
                }
            }
        }
        // unconditionally set oldProgram to undefined to prevent it from being captured in closure
        oldProgram = undefined;
        program = {
            getRootFileNames: function () { return rootNames; },
            getSourceFile: getSourceFile,
            getSourceFileByPath: getSourceFileByPath,
            getSourceFiles: function () { return files; },
            getMissingFilePaths: function () { return missingFilePaths; },
            getCompilerOptions: function () { return options; },
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getOptionsDiagnostics: getOptionsDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getDeclarationDiagnostics: getDeclarationDiagnostics,
            getTypeChecker: getTypeChecker,
            getClassifiableNames: getClassifiableNames,
            getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker,
            getCommonSourceDirectory: getCommonSourceDirectory,
            emit: emit,
            getCurrentDirectory: function () { return currentDirectory; },
            getNodeCount: function () { return getDiagnosticsProducingTypeChecker().getNodeCount(); },
            getIdentifierCount: function () { return getDiagnosticsProducingTypeChecker().getIdentifierCount(); },
            getSymbolCount: function () { return getDiagnosticsProducingTypeChecker().getSymbolCount(); },
            getTypeCount: function () { return getDiagnosticsProducingTypeChecker().getTypeCount(); },
            getFileProcessingDiagnostics: function () { return fileProcessingDiagnostics; },
            getResolvedTypeReferenceDirectives: function () { return resolvedTypeReferenceDirectives; },
            isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
            isSourceFileDefaultLibrary: isSourceFileDefaultLibrary,
            dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker,
            getSourceFileFromReference: getSourceFileFromReference,
            sourceFileToPackageName: sourceFileToPackageName,
            redirectTargetsSet: redirectTargetsSet
        };
        verifyCompilerOptions();
        ts.performance.mark("afterProgram");
        ts.performance.measure("Program", "beforeProgram", "afterProgram");
        return program;
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCommonSourceDirectory() {
            if (commonSourceDirectory === undefined) {
                var emittedFiles = ts.filter(files, function (file) { return ts.sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary); });
                if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
                    // If a rootDir is specified and is valid use it as the commonSourceDirectory
                    commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
                }
                else {
                    commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
                }
                if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) {
                    // Make sure directory path ends with directory separator so this string can directly
                    // used to replace with "" to get the relative path of the source file and the relative path doesn't
                    // start with / making it rooted path
                    commonSourceDirectory += ts.directorySeparator;
                }
            }
            return commonSourceDirectory;
        }
        function getClassifiableNames() {
            if (!classifiableNames) {
                // Initialize a checker so that all our files are bound.
                getTypeChecker();
                classifiableNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
                    var sourceFile = files_2[_i];
                    ts.copyEntries(sourceFile.classifiableNames, classifiableNames);
                }
            }
            return classifiableNames;
        }
        function resolveModuleNamesReusingOldState(moduleNames, containingFile, file, oldProgramState) {
            if (structuralIsReused === 0 /* Not */ && !file.ambientModuleNames.length) {
                // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
                // the best we can do is fallback to the default logic.
                return resolveModuleNamesWorker(moduleNames, containingFile);
            }
            var oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile);
            if (oldSourceFile !== file && file.resolvedModules) {
                // `file` was created for the new program.
                //
                // We only set `file.resolvedModules` via work from the current function,
                // so it is defined iff we already called the current function on `file`.
                // That call happened no later than the creation of the `file` object,
                // which per above occured during the current program creation.
                // Since we assume the filesystem does not change during program creation,
                // it is safe to reuse resolutions from the earlier call.
                var result_4 = [];
                for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
                    var moduleName = moduleNames_1[_i];
                    var resolvedModule = file.resolvedModules.get(moduleName);
                    result_4.push(resolvedModule);
                }
                return result_4;
            }
            // At this point, we know at least one of the following hold:
            // - file has local declarations for ambient modules
            // - old program state is available
            // With this information, we can infer some module resolutions without performing resolution.
            /** An ordered list of module names for which we cannot recover the resolution. */
            var unknownModuleNames;
            /**
             * The indexing of elements in this list matches that of `moduleNames`.
             *
             * Before combining results, result[i] is in one of the following states:
             * * undefined: needs to be recomputed,
             * * predictedToResolveToAmbientModuleMarker: known to be an ambient module.
             * Needs to be reset to undefined before returning,
             * * ResolvedModuleFull instance: can be reused.
             */
            var result;
            var reusedNames;
            /** A transient placeholder used to mark predicted resolution in the result list. */
            var predictedToResolveToAmbientModuleMarker = {};
            for (var i = 0; i < moduleNames.length; i++) {
                var moduleName = moduleNames[i];
                // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
                if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
                    var oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName);
                    if (oldResolvedModule) {
                        if (ts.isTraceEnabled(options, host)) {
                            ts.trace(host, ts.Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
                        }
                        (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule;
                        (reusedNames || (reusedNames = [])).push(moduleName);
                        continue;
                    }
                }
                // We know moduleName resolves to an ambient module provided that moduleName:
                // - is in the list of ambient modules locally declared in the current source file.
                // - resolved to an ambient module in the old program whose declaration is in an unmodified file
                //   (so the same module declaration will land in the new program)
                var resolvesToAmbientModuleInNonModifiedFile = false;
                if (ts.contains(file.ambientModuleNames, moduleName)) {
                    resolvesToAmbientModuleInNonModifiedFile = true;
                    if (ts.isTraceEnabled(options, host)) {
                        ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
                    }
                }
                else {
                    resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState);
                }
                if (resolvesToAmbientModuleInNonModifiedFile) {
                    (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker;
                }
                else {
                    // Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
                    (unknownModuleNames || (unknownModuleNames = [])).push(moduleName);
                }
            }
            var resolutions = unknownModuleNames && unknownModuleNames.length
                ? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames)
                : ts.emptyArray;
            // Combine results of resolutions and predicted results
            if (!result) {
                // There were no unresolved/ambient resolutions.
                ts.Debug.assert(resolutions.length === moduleNames.length);
                return resolutions;
            }
            var j = 0;
            for (var i = 0; i < result.length; i++) {
                if (result[i]) {
                    // `result[i]` is either a `ResolvedModuleFull` or a marker.
                    // If it is the former, we can leave it as is.
                    if (result[i] === predictedToResolveToAmbientModuleMarker) {
                        result[i] = undefined;
                    }
                }
                else {
                    result[i] = resolutions[j];
                    j++;
                }
            }
            ts.Debug.assert(j === resolutions.length);
            return result;
            // If we change our policy of rechecking failed lookups on each program create,
            // we should adjust the value returned here.
            function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState) {
                var resolutionToFile = ts.getResolvedModule(oldProgramState.file, moduleName);
                if (resolutionToFile) {
                    // module used to be resolved to file - ignore it
                    return false;
                }
                var ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
                if (!(ambientModule && ambientModule.declarations)) {
                    return false;
                }
                // at least one of declarations should come from non-modified source file
                var firstUnmodifiedFile = ts.forEach(ambientModule.declarations, function (d) {
                    var f = ts.getSourceFileOfNode(d);
                    return !ts.contains(oldProgramState.modifiedFilePaths, f.path) && f;
                });
                if (!firstUnmodifiedFile) {
                    return false;
                }
                if (ts.isTraceEnabled(options, host)) {
                    ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, firstUnmodifiedFile.fileName);
                }
                return true;
            }
        }
        function tryReuseStructureFromOldProgram() {
            if (!oldProgram) {
                return 0 /* Not */;
            }
            // check properties that can affect structure of the program or module resolution strategy
            // if any of these properties has changed - structure cannot be reused
            var oldOptions = oldProgram.getCompilerOptions();
            if (ts.changesAffectModuleResolution(oldOptions, options)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            ts.Debug.assert(!(oldProgram.structureIsReused & (2 /* Completely */ | 1 /* SafeModules */)));
            // there is an old program, check if we can reuse its structure
            var oldRootNames = oldProgram.getRootFileNames();
            if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            // check if program source files has changed in the way that can affect structure of the program
            var newSourceFiles = [];
            var filePaths = [];
            var modifiedSourceFiles = [];
            oldProgram.structureIsReused = 2 /* Completely */;
            // If the missing file paths are now present, it can change the progam structure,
            // and hence cant reuse the structure.
            // This is same as how we dont reuse the structure if one of the file from old program is now missing
            if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            var oldSourceFiles = oldProgram.getSourceFiles();
            var SeenPackageName;
            (function (SeenPackageName) {
                SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists";
                SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified";
            })(SeenPackageName || (SeenPackageName = {}));
            var seenPackageNames = ts.createMap();
            for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) {
                var oldSourceFile = oldSourceFiles_2[_i];
                var newSourceFile = host.getSourceFileByPath
                    ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target, /*onError*/ undefined, shouldCreateNewSourceFile)
                    : host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile);
                if (!newSourceFile) {
                    return oldProgram.structureIsReused = 0 /* Not */;
                }
                ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`");
                var fileChanged = void 0;
                if (oldSourceFile.redirectInfo) {
                    // We got `newSourceFile` by path, so it is actually for the unredirected file.
                    // This lets us know if the unredirected file has changed. If it has we should break the redirect.
                    if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
                        // Underlying file has changed. Might not redirect anymore. Must rebuild program.
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                    newSourceFile = oldSourceFile; // Use the redirect.
                }
                else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) {
                    // If a redirected-to source file changes, the redirect may be broken.
                    if (newSourceFile !== oldSourceFile) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                }
                else {
                    fileChanged = newSourceFile !== oldSourceFile;
                }
                newSourceFile.path = oldSourceFile.path;
                filePaths.push(newSourceFile.path);
                var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
                if (packageName !== undefined) {
                    // If there are 2 different source files for the same package name and at least one of them changes,
                    // they might become redirects. So we must rebuild the program.
                    var prevKind = seenPackageNames.get(packageName);
                    var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
                    if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    seenPackageNames.set(packageName, newKind);
                }
                if (fileChanged) {
                    // The `newSourceFile` object was created for the new program.
                    if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
                        // value of no-default-lib has changed
                        // this will affect if default library is injected into the list of files
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check tripleslash references
                    if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
                        // tripleslash references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check imports and module augmentations
                    collectExternalModuleReferences(newSourceFile);
                    if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
                        // imports has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
                        // moduleAugmentations has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if ((oldSourceFile.flags & 524288 /* PossiblyContainsDynamicImport */) !== (newSourceFile.flags & 524288 /* PossiblyContainsDynamicImport */)) {
                        // dynamicImport has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'types' references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // tentatively approve the file
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                else if (hasInvalidatedResolution(oldSourceFile.path)) {
                    // 'module/types' references could have changed
                    oldProgram.structureIsReused = 1 /* SafeModules */;
                    // add file to the modified list so that we will resolve it later
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                // if file has passed all checks it should be safe to reuse it
                newSourceFiles.push(newSourceFile);
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; });
            // try to verify results of module resolution
            for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) {
                var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile;
                var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
                if (resolveModuleNamesWorker) {
                    var moduleNames = getModuleNames(newSourceFile);
                    var oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths: modifiedFilePaths };
                    var resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
                    // ensure that module resolution results are still correct
                    var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo);
                    if (resolutionsChanged) {
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                        newSourceFile.resolvedModules = ts.zipToMap(moduleNames, resolutions);
                    }
                    else {
                        newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
                    }
                }
                if (resolveTypeReferenceDirectiveNamesWorker) {
                    var typesReferenceDirectives = ts.map(newSourceFile.typeReferenceDirectives, function (x) { return x.fileName; });
                    var resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
                    // ensure that types resolutions are still correct
                    var resolutionsChanged = ts.hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, ts.typeDirectiveIsEqualTo);
                    if (resolutionsChanged) {
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                        newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToMap(typesReferenceDirectives, resolutions);
                    }
                    else {
                        newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
                    }
                }
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            if (host.hasChangedAutomaticTypeDirectiveNames) {
                return oldProgram.structureIsReused = 1 /* SafeModules */;
            }
            missingFilePaths = oldProgram.getMissingFilePaths();
            // update fileName -> file mapping
            for (var i = 0; i < newSourceFiles.length; i++) {
                filesByName.set(filePaths[i], newSourceFiles[i]);
                // Set the file as found during node modules search if it was found that way in old progra,
                if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i]))) {
                    sourceFilesFoundSearchingNodeModules.set(filePaths[i], true);
                }
            }
            files = newSourceFiles;
            fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
            for (var _c = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _c < modifiedSourceFiles_2.length; _c++) {
                var modifiedFile = modifiedSourceFiles_2[_c];
                fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
            }
            resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
            sourceFileToPackageName = oldProgram.sourceFileToPackageName;
            redirectTargetsSet = oldProgram.redirectTargetsSet;
            return oldProgram.structureIsReused = 2 /* Completely */;
        }
        function getEmitHost(writeFileCallback) {
            return {
                getCanonicalFileName: getCanonicalFileName,
                getCommonSourceDirectory: program.getCommonSourceDirectory,
                getCompilerOptions: program.getCompilerOptions,
                getCurrentDirectory: function () { return currentDirectory; },
                getNewLine: function () { return host.getNewLine(); },
                getSourceFile: program.getSourceFile,
                getSourceFileByPath: program.getSourceFileByPath,
                getSourceFiles: program.getSourceFiles,
                isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
                writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }),
                isEmitBlocked: isEmitBlocked,
            };
        }
        function isSourceFileFromExternalLibrary(file) {
            return sourceFilesFoundSearchingNodeModules.get(file.path);
        }
        function isSourceFileDefaultLibrary(file) {
            if (file.hasNoDefaultLib) {
                return true;
            }
            if (!options.noLib) {
                return false;
            }
            // If '--lib' is not specified, include default library file according to '--target'
            // otherwise, using options specified in '--lib' instead of '--target' default library file
            if (!options.lib) {
                return ts.compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
            }
            else {
                return ts.forEach(options.lib, function (libFileName) { return ts.compareStrings(file.fileName, ts.combinePaths(defaultLibraryPath, libFileName), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */; });
            }
        }
        function getDiagnosticsProducingTypeChecker() {
            return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true));
        }
        function dropDiagnosticsProducingTypeChecker() {
            diagnosticsProducingTypeChecker = undefined;
        }
        function getTypeChecker() {
            return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false));
        }
        function emit(sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers) {
            return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers); });
        }
        function isEmitBlocked(emitFileName) {
            return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
        }
        function emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            var declarationDiagnostics = [];
            if (options.noEmit) {
                return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
            }
            // If the noEmitOnError flag is set, then check if we have any errors so far.  If so,
            // immediately bail out.  Note that we pass 'undefined' for 'sourceFile' so that we
            // get any preEmit diagnostics, not just the ones
            if (options.noEmitOnError) {
                var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
                if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
                    declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
                }
                if (diagnostics.length > 0 || declarationDiagnostics.length > 0) {
                    return {
                        diagnostics: ts.concatenate(diagnostics, declarationDiagnostics),
                        sourceMaps: undefined,
                        emittedFiles: undefined,
                        emitSkipped: true
                    };
                }
            }
            // Create the emit resolver outside of the "emitTime" tracking code below.  That way
            // any cost associated with it (like type checking) are appropriate associated with
            // the type-checking counter.
            //
            // If the -out option is specified, we should not pass the source file to getEmitResolver.
            // This is because in the -out scenario all files need to be emitted, and therefore all
            // files need to be type checked. And the way to specify that all files need to be type
            // checked is to not pass the file to getEmitResolver.
            var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
            ts.performance.mark("beforeEmit");
            var transformers = emitOnlyDtsFiles ? [] : ts.getTransformers(options, customTransformers);
            var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, emitOnlyDtsFiles, transformers);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getSourceFile(fileName) {
            return getSourceFileByPath(toPath(fileName));
        }
        function getSourceFileByPath(path) {
            return filesByName.get(path);
        }
        function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
            if (sourceFile) {
                return getDiagnostics(sourceFile, cancellationToken);
            }
            return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), function (sourceFile) {
                if (cancellationToken) {
                    cancellationToken.throwIfCancellationRequested();
                }
                return getDiagnostics(sourceFile, cancellationToken);
            }));
        }
        function getSyntacticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
        }
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
        }
        function getDeclarationDiagnostics(sourceFile, cancellationToken) {
            var options = program.getCompilerOptions();
            // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
            if (!sourceFile || options.out || options.outFile) {
                return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
            }
            else {
                return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
            }
        }
        function getSyntacticDiagnosticsForFile(sourceFile) {
            // For JavaScript files, we report semantic errors for using TypeScript-only
            // constructs from within a JavaScript file as syntactic errors.
            if (ts.isSourceFileJavaScript(sourceFile)) {
                if (!sourceFile.additionalSyntacticDiagnostics) {
                    sourceFile.additionalSyntacticDiagnostics = getJavaScriptSyntacticDiagnosticsForFile(sourceFile);
                    if (ts.isCheckJsEnabledForFile(sourceFile, options)) {
                        sourceFile.additionalSyntacticDiagnostics = ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.jsDocDiagnostics);
                    }
                }
                return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
            }
            return sourceFile.parseDiagnostics;
        }
        function runWithCancellationToken(func) {
            try {
                return func();
            }
            catch (e) {
                if (e instanceof ts.OperationCanceledException) {
                    // We were canceled while performing the operation.  Because our type checker
                    // might be a bad state, we need to throw it away.
                    //
                    // Note: we are overly aggressive here.  We do not actually *have* to throw away
                    // the "noDiagnosticsTypeChecker".  However, for simplicity, i'd like to keep
                    // the lifetimes of these two TypeCheckers the same.  Also, we generally only
                    // cancel when the user has made a change anyways.  And, in that case, we (the
                    // program instance) will get thrown away anyways.  So trying to keep one of
                    // these type checkers alive doesn't serve much purpose.
                    noDiagnosticsTypeChecker = undefined;
                    diagnosticsProducingTypeChecker = undefined;
                }
                throw e;
            }
        }
        function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
        }
        function getSemanticDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                // If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
                // If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
                // '/// <reference no-default-lib="true"/>' directive.
                if (options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) {
                    return ts.emptyArray;
                }
                var typeChecker = getDiagnosticsProducingTypeChecker();
                ts.Debug.assert(!!sourceFile.bindDiagnostics);
                // By default, only type-check .ts, .tsx, and 'External' files (external files are added by plugins)
                var includeBindAndCheckDiagnostics = sourceFile.scriptKind === 3 /* TS */ || sourceFile.scriptKind === 4 /* TSX */ ||
                    sourceFile.scriptKind === 5 /* External */ || ts.isCheckJsEnabledForFile(sourceFile, options);
                var bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray;
                var checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray;
                var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
                var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
                var diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
                return ts.filter(diagnostics, shouldReportDiagnostic);
            });
        }
        /**
         * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines
         */
        function shouldReportDiagnostic(diagnostic) {
            var file = diagnostic.file, start = diagnostic.start;
            if (file) {
                var lineStarts = ts.getLineStarts(file);
                var line = ts.computeLineAndCharacterOfPosition(lineStarts, start).line;
                while (line > 0) {
                    var previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
                    var result = ignoreDiagnosticCommentRegEx.exec(previousLineText);
                    if (!result) {
                        // non-empty line
                        return true;
                    }
                    if (result[3]) {
                        // @ts-ignore
                        return false;
                    }
                    line--;
                }
            }
            return true;
        }
        function getJavaScriptSyntacticDiagnosticsForFile(sourceFile) {
            return runWithCancellationToken(function () {
                var diagnostics = [];
                var parent = sourceFile;
                walk(sourceFile);
                return diagnostics;
                function walk(node) {
                    // Return directly from the case if the given node doesnt want to visit each child
                    // Otherwise break to visit each child
                    switch (parent.kind) {
                        case 146 /* Parameter */:
                        case 149 /* PropertyDeclaration */:
                            if (parent.questionToken === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
                                return;
                            }
                        // falls through
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                        case 152 /* Constructor */:
                        case 153 /* GetAccessor */:
                        case 154 /* SetAccessor */:
                        case 186 /* FunctionExpression */:
                        case 228 /* FunctionDeclaration */:
                        case 187 /* ArrowFunction */:
                        case 226 /* VariableDeclaration */:
                            // type annotation
                            if (parent.type === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.types_can_only_be_used_in_a_ts_file));
                                return;
                            }
                    }
                    switch (node.kind) {
                        case 237 /* ImportEqualsDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_a_ts_file));
                            return;
                        case 243 /* ExportAssignment */:
                            if (node.isExportEquals) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                        case 259 /* HeritageClause */:
                            var heritageClause = node;
                            if (heritageClause.token === 108 /* ImplementsKeyword */) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                        case 230 /* InterfaceDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
                            return;
                        case 233 /* ModuleDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
                            return;
                        case 231 /* TypeAliasDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
                            return;
                        case 232 /* EnumDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
                            return;
                        case 203 /* NonNullExpression */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.non_null_assertions_can_only_be_used_in_a_ts_file));
                            return;
                        case 202 /* AsExpression */:
                            diagnostics.push(createDiagnosticForNode(node.type, ts.Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
                            return;
                        case 184 /* TypeAssertionExpression */:
                            ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
                    }
                    var prevParent = parent;
                    parent = node;
                    ts.forEachChild(node, walk, walkArray);
                    parent = prevParent;
                }
                function walkArray(nodes) {
                    if (parent.decorators === nodes && !options.experimentalDecorators) {
                        diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning));
                    }
                    switch (parent.kind) {
                        case 229 /* ClassDeclaration */:
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                        case 152 /* Constructor */:
                        case 153 /* GetAccessor */:
                        case 154 /* SetAccessor */:
                        case 186 /* FunctionExpression */:
                        case 228 /* FunctionDeclaration */:
                        case 187 /* ArrowFunction */:
                            // Check type parameters
                            if (nodes === parent.typeParameters) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
                                return;
                            }
                        // falls through
                        case 208 /* VariableStatement */:
                            // Check modifiers
                            if (nodes === parent.modifiers) {
                                return checkModifiers(nodes, parent.kind === 208 /* VariableStatement */);
                            }
                            break;
                        case 149 /* PropertyDeclaration */:
                            // Check modifiers of property declaration
                            if (nodes === parent.modifiers) {
                                for (var _i = 0, _a = nodes; _i < _a.length; _i++) {
                                    var modifier = _a[_i];
                                    if (modifier.kind !== 115 /* StaticKeyword */) {
                                        diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
                                    }
                                }
                                return;
                            }
                            break;
                        case 146 /* Parameter */:
                            // Check modifiers of parameter declaration
                            if (nodes === parent.modifiers) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                        case 181 /* CallExpression */:
                        case 182 /* NewExpression */:
                        case 201 /* ExpressionWithTypeArguments */:
                            // Check type arguments
                            if (nodes === parent.typeArguments) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
                                return;
                            }
                            break;
                    }
                    for (var _b = 0, nodes_8 = nodes; _b < nodes_8.length; _b++) {
                        var node = nodes_8[_b];
                        walk(node);
                    }
                }
                function checkModifiers(modifiers, isConstValid) {
                    for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
                        var modifier = modifiers_1[_i];
                        switch (modifier.kind) {
                            case 76 /* ConstKeyword */:
                                if (isConstValid) {
                                    continue;
                                }
                            // to report error,
                            // falls through
                            case 114 /* PublicKeyword */:
                            case 112 /* PrivateKeyword */:
                            case 113 /* ProtectedKeyword */:
                            case 131 /* ReadonlyKeyword */:
                            case 124 /* DeclareKeyword */:
                            case 117 /* AbstractKeyword */:
                                diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
                                break;
                            // These are all legal modifiers.
                            case 115 /* StaticKeyword */:
                            case 84 /* ExportKeyword */:
                            case 79 /* DefaultKeyword */:
                        }
                    }
                }
                function createDiagnosticForNodeArray(nodes, message, arg0, arg1, arg2) {
                    var start = nodes.pos;
                    return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
                }
                // Since these are syntactic diagnostics, parent might not have been set
                // this means the sourceFile cannot be infered from the node
                function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
                    return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
                }
            });
        }
        function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
        }
        function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
                // Don't actually write any files since we're just getting diagnostics.
                return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile);
            });
        }
        function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) {
            var cachedResult = sourceFile
                ? cache.perFile && cache.perFile.get(sourceFile.path)
                : cache.allDiagnostics;
            if (cachedResult) {
                return cachedResult;
            }
            var result = getDiagnostics(sourceFile, cancellationToken) || ts.emptyArray;
            if (sourceFile) {
                if (!cache.perFile) {
                    cache.perFile = ts.createMap();
                }
                cache.perFile.set(sourceFile.path, result);
            }
            else {
                cache.allDiagnostics = result;
            }
            return result;
        }
        function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
            return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
        }
        function getOptionsDiagnostics() {
            return ts.sortAndDeduplicateDiagnostics(ts.concatenate(fileProcessingDiagnostics.getGlobalDiagnostics(), ts.concatenate(programDiagnostics.getGlobalDiagnostics(), options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : [])));
        }
        function getGlobalDiagnostics() {
            return ts.sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice());
        }
        function processRootFile(fileName, isDefaultLib) {
            processSourceFile(ts.normalizePath(fileName), isDefaultLib, /*packageId*/ undefined);
        }
        function fileReferenceIsEqualTo(a, b) {
            return a.fileName === b.fileName;
        }
        function moduleNameIsEqualTo(a, b) {
            return a.kind === 9 /* StringLiteral */
                ? b.kind === 9 /* StringLiteral */ && a.text === b.text
                : b.kind === 71 /* Identifier */ && a.escapedText === b.escapedText;
        }
        function collectExternalModuleReferences(file) {
            if (file.imports) {
                return;
            }
            var isJavaScriptFile = ts.isSourceFileJavaScript(file);
            var isExternalModuleFile = ts.isExternalModule(file);
            // file.imports may not be undefined if there exists dynamic import
            var imports;
            var moduleAugmentations;
            var ambientModules;
            // If we are importing helpers, we need to add a synthetic reference to resolve the
            // helpers library.
            if (options.importHelpers
                && (options.isolatedModules || isExternalModuleFile)
                && !file.isDeclarationFile) {
                // synthesize 'import "tslib"' declaration
                var externalHelpersModuleReference = ts.createLiteral(ts.externalHelpersModuleNameText);
                var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined);
                externalHelpersModuleReference.parent = importDecl;
                importDecl.parent = file;
                imports = [externalHelpersModuleReference];
            }
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                collectModuleReferences(node, /*inAmbientModule*/ false);
                if ((file.flags & 524288 /* PossiblyContainsDynamicImport */) || isJavaScriptFile) {
                    collectDynamicImportOrRequireCalls(node);
                }
            }
            file.imports = imports || ts.emptyArray;
            file.moduleAugmentations = moduleAugmentations || ts.emptyArray;
            file.ambientModuleNames = ambientModules || ts.emptyArray;
            return;
            function collectModuleReferences(node, inAmbientModule) {
                switch (node.kind) {
                    case 238 /* ImportDeclaration */:
                    case 237 /* ImportEqualsDeclaration */:
                    case 244 /* ExportDeclaration */:
                        var moduleNameExpr = ts.getExternalModuleName(node);
                        if (!moduleNameExpr || !ts.isStringLiteral(moduleNameExpr)) {
                            break;
                        }
                        if (!moduleNameExpr.text) {
                            break;
                        }
                        // TypeScript 1.0 spec (April 2014): 12.1.6
                        // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
                        // only through top - level external module names. Relative external module names are not permitted.
                        if (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
                            (imports || (imports = [])).push(moduleNameExpr);
                        }
                        break;
                    case 233 /* ModuleDeclaration */:
                        if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasModifier(node, 2 /* Ambient */) || file.isDeclarationFile)) {
                            var moduleName = node.name;
                            var nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
                            // Ambient module declarations can be interpreted as augmentations for some existing external modules.
                            // This will happen in two cases:
                            // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
                            // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
                            //   immediately nested in top level ambient module declaration .
                            if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) {
                                (moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
                            }
                            else if (!inAmbientModule) {
                                if (file.isDeclarationFile) {
                                    // for global .d.ts files record name of ambient module
                                    (ambientModules || (ambientModules = [])).push(nameText);
                                }
                                // An AmbientExternalModuleDeclaration declares an external module.
                                // This type of declaration is permitted only in the global module.
                                // The StringLiteral must specify a top - level external module name.
                                // Relative external module names are not permitted
                                // NOTE: body of ambient module is always a module block, if it exists
                                var body = node.body;
                                if (body) {
                                    for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
                                        var statement = _a[_i];
                                        collectModuleReferences(statement, /*inAmbientModule*/ true);
                                    }
                                }
                            }
                        }
                }
            }
            function collectDynamicImportOrRequireCalls(node) {
                if (ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
                    (imports || (imports = [])).push(node.arguments[0]);
                }
                else if (ts.isImportCall(node) && node.arguments.length === 1 && node.arguments[0].kind === 9 /* StringLiteral */) {
                    (imports || (imports = [])).push(node.arguments[0]);
                }
                else {
                    ts.forEachChild(node, collectDynamicImportOrRequireCalls);
                }
            }
        }
        /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
        function getSourceFileFromReference(referencingFile, ref) {
            return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), function (fileName) { return filesByName.get(toPath(fileName)); });
        }
        function getSourceFileFromReferenceWorker(fileName, getSourceFile, fail, refFile) {
            if (ts.hasExtension(fileName)) {
                if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensions, function (extension) { return ts.fileExtensionIs(host.getCanonicalFileName(fileName), extension); })) {
                    if (fail)
                        fail(ts.Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
                    return undefined;
                }
                var sourceFile = getSourceFile(fileName);
                if (fail) {
                    if (!sourceFile) {
                        fail(ts.Diagnostics.File_0_not_found, fileName);
                    }
                    else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
                        fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself);
                    }
                }
                return sourceFile;
            }
            else {
                var sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName);
                if (sourceFileNoExtension)
                    return sourceFileNoExtension;
                if (fail && options.allowNonTsExtensions) {
                    fail(ts.Diagnostics.File_0_not_found, fileName);
                    return undefined;
                }
                var sourceFileWithAddedExtension = ts.forEach(supportedExtensions, function (extension) { return getSourceFile(fileName + extension); });
                if (fail && !sourceFileWithAddedExtension)
                    fail(ts.Diagnostics.File_0_not_found, fileName + ".ts" /* Ts */);
                return sourceFileWithAddedExtension;
            }
        }
        /** This has side effects through `findSourceFile`. */
        function processSourceFile(fileName, isDefaultLib, packageId, refFile, refPos, refEnd) {
            getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, packageId); }, function (diagnostic) {
                var args = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    args[_i - 1] = arguments[_i];
                }
                fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
                    ? ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, diagnostic].concat(args)) : ts.createCompilerDiagnostic.apply(void 0, [diagnostic].concat(args)));
            }, refFile);
        }
        function reportFileNamesDifferOnlyInCasingError(fileName, existingFileName, refFile, refPos, refEnd) {
            if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
                fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName));
            }
            else {
                fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName));
            }
        }
        function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) {
            var redirect = Object.create(redirectTarget);
            redirect.fileName = fileName;
            redirect.path = path;
            redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected };
            Object.defineProperties(redirect, {
                id: {
                    get: function () { return this.redirectInfo.redirectTarget.id; },
                    set: function (value) { this.redirectInfo.redirectTarget.id = value; },
                },
                symbol: {
                    get: function () { return this.redirectInfo.redirectTarget.symbol; },
                    set: function (value) { this.redirectInfo.redirectTarget.symbol = value; },
                },
            });
            return redirect;
        }
        // Get source file from normalized fileName
        function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) {
            if (filesByName.has(path)) {
                var file_1 = filesByName.get(path);
                // try to check if we've already seen this file but with a different casing in path
                // NOTE: this only makes sense for case-insensitive file systems
                if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) {
                    reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd);
                }
                // If the file was previously found via a node_modules search, but is now being processed as a root file,
                // then everything it sucks in may also be marked incorrectly, and needs to be checked again.
                if (file_1 && sourceFilesFoundSearchingNodeModules.get(file_1.path) && currentNodeModulesDepth === 0) {
                    sourceFilesFoundSearchingNodeModules.set(file_1.path, false);
                    if (!options.noResolve) {
                        processReferencedFiles(file_1, isDefaultLib);
                        processTypeReferenceDirectives(file_1);
                    }
                    modulesWithElidedImports.set(file_1.path, false);
                    processImportedModules(file_1);
                }
                else if (file_1 && modulesWithElidedImports.get(file_1.path)) {
                    if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
                        modulesWithElidedImports.set(file_1.path, false);
                        processImportedModules(file_1);
                    }
                }
                return file_1;
            }
            // We haven't looked for this file, do so now and cache result
            var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) {
                if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
                    fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
                }
                else {
                    fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
                }
            }, shouldCreateNewSourceFile);
            if (packageId) {
                var packageIdKey = packageId.name + "/" + packageId.subModuleName + "@" + packageId.version;
                var fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
                if (fileFromPackageId) {
                    // Some other SourceFile already exists with this package name and version.
                    // Instead of creating a duplicate, just redirect to the existing one.
                    var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path);
                    redirectTargetsSet.set(fileFromPackageId.path, true);
                    filesByName.set(path, dupFile);
                    sourceFileToPackageName.set(path, packageId.name);
                    files.push(dupFile);
                    return dupFile;
                }
                else if (file) {
                    // This is the first source file to have this packageId.
                    packageIdToSourceFile.set(packageIdKey, file);
                    sourceFileToPackageName.set(path, packageId.name);
                }
            }
            filesByName.set(path, file);
            if (file) {
                sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
                file.path = path;
                if (host.useCaseSensitiveFileNames()) {
                    var pathLowerCase = path.toLowerCase();
                    // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
                    var existingFile = filesByNameIgnoreCase.get(pathLowerCase);
                    if (existingFile) {
                        reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
                    }
                    else {
                        filesByNameIgnoreCase.set(pathLowerCase, file);
                    }
                }
                skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
                if (!options.noResolve) {
                    processReferencedFiles(file, isDefaultLib);
                    processTypeReferenceDirectives(file);
                }
                // always process imported modules to record module name resolutions
                processImportedModules(file);
                if (isDefaultLib) {
                    files.unshift(file);
                }
                else {
                    files.push(file);
                }
            }
            return file;
        }
        function processReferencedFiles(file, isDefaultLib) {
            ts.forEach(file.referencedFiles, function (ref) {
                var referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
                processSourceFile(referencedFileName, isDefaultLib, /*packageId*/ undefined, file, ref.pos, ref.end);
            });
        }
        function processTypeReferenceDirectives(file) {
            // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
            var typeDirectives = ts.map(file.typeReferenceDirectives, function (ref) { return ref.fileName.toLocaleLowerCase(); });
            var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName);
            for (var i = 0; i < typeDirectives.length; i++) {
                var ref = file.typeReferenceDirectives[i];
                var resolvedTypeReferenceDirective = resolutions[i];
                // store resolved type directive on the file
                var fileName = ref.fileName.toLocaleLowerCase();
                ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
                processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end);
            }
        }
        function processTypeReferenceDirective(typeReferenceDirective, resolvedTypeReferenceDirective, refFile, refPos, refEnd) {
            // If we already found this library as a primary reference - nothing to do
            var previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective);
            if (previousResolution && previousResolution.primary) {
                return;
            }
            var saveResolution = true;
            if (resolvedTypeReferenceDirective) {
                if (resolvedTypeReferenceDirective.primary) {
                    // resolved from the primary path
                    processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
                }
                else {
                    // If we already resolved to this file, it must have been a secondary reference. Check file contents
                    // for sameness and possibly issue an error
                    if (previousResolution) {
                        // Don't bother reading the file again if it's the same file.
                        if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
                            var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
                            if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) {
                                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName));
                            }
                        }
                        // don't overwrite previous resolution result
                        saveResolution = false;
                    }
                    else {
                        // First resolution of this library
                        processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
                    }
                }
            }
            else {
                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective));
            }
            if (saveResolution) {
                resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective);
            }
        }
        function createDiagnostic(refFile, refPos, refEnd, message) {
            var args = [];
            for (var _i = 4; _i < arguments.length; _i++) {
                args[_i - 4] = arguments[_i];
            }
            if (refFile === undefined || refPos === undefined || refEnd === undefined) {
                return ts.createCompilerDiagnostic.apply(void 0, [message].concat(args));
            }
            else {
                return ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, message].concat(args));
            }
        }
        function getCanonicalFileName(fileName) {
            return host.getCanonicalFileName(fileName);
        }
        function processImportedModules(file) {
            collectExternalModuleReferences(file);
            if (file.imports.length || file.moduleAugmentations.length) {
                // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
                var moduleNames = getModuleNames(file);
                var oldProgramState = { program: oldProgram, file: file, modifiedFilePaths: modifiedFilePaths };
                var resolutions = resolveModuleNamesReusingOldState(moduleNames, ts.getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
                ts.Debug.assert(resolutions.length === moduleNames.length);
                for (var i = 0; i < moduleNames.length; i++) {
                    var resolution = resolutions[i];
                    ts.setResolvedModule(file, moduleNames[i], resolution);
                    if (!resolution) {
                        continue;
                    }
                    var isFromNodeModulesSearch = resolution.isExternalLibraryImport;
                    var isJsFile = !ts.extensionIsTypeScript(resolution.extension);
                    var isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
                    var resolvedFileName = resolution.resolvedFileName;
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth++;
                    }
                    // add file to program only if:
                    // - resolution was successful
                    // - noResolve is falsy
                    // - module name comes from the list of imports
                    // - it's not a top level JavaScript module that exceeded the search max
                    var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
                    // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
                    // This may still end up being an untyped module -- the file won't be included but imports will be allowed.
                    var shouldAddFile = resolvedFileName
                        && !getResolutionDiagnostic(options, resolution)
                        && !options.noResolve
                        && i < file.imports.length
                        && !elideImport
                        && !(isJsFile && !options.allowJs);
                    if (elideImport) {
                        modulesWithElidedImports.set(file.path, true);
                    }
                    else if (shouldAddFile) {
                        var path = toPath(resolvedFileName);
                        var pos = ts.skipTrivia(file.text, file.imports[i].pos);
                        findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end, resolution.packageId);
                    }
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth--;
                    }
                }
            }
            else {
                // no imports - drop cached module resolutions
                file.resolvedModules = undefined;
            }
        }
        function computeCommonSourceDirectory(sourceFiles) {
            var fileNames = [];
            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
                var file = sourceFiles_2[_i];
                if (!file.isDeclarationFile) {
                    fileNames.push(file.fileName);
                }
            }
            return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName);
        }
        function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
            var allFilesBelongToPath = true;
            if (sourceFiles) {
                var absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory));
                for (var _i = 0, sourceFiles_3 = sourceFiles; _i < sourceFiles_3.length; _i++) {
                    var sourceFile = sourceFiles_3[_i];
                    if (!sourceFile.isDeclarationFile) {
                        var absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
                        if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
                            programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
                            allFilesBelongToPath = false;
                        }
                    }
                }
            }
            return allFilesBelongToPath;
        }
        function verifyCompilerOptions() {
            if (options.isolatedModules) {
                if (options.declaration) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
                }
                if (options.noEmitOnError) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules");
                }
                if (options.out) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
                }
                if (options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
                }
            }
            if (options.inlineSourceMap) {
                if (options.sourceMap) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
                }
                if (options.mapRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
                }
            }
            if (options.paths && options.baseUrl === undefined) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
            }
            if (options.paths) {
                for (var key in options.paths) {
                    if (!ts.hasProperty(options.paths, key)) {
                        continue;
                    }
                    if (!ts.hasZeroOrOneAsteriskCharacter(key)) {
                        createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
                    }
                    if (ts.isArray(options.paths[key])) {
                        var len = options.paths[key].length;
                        if (len === 0) {
                            createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
                        }
                        for (var i = 0; i < len; i++) {
                            var subst = options.paths[key][i];
                            var typeOfSubst = typeof subst;
                            if (typeOfSubst === "string") {
                                if (!ts.hasZeroOrOneAsteriskCharacter(subst)) {
                                    createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key);
                                }
                            }
                            else {
                                createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
                            }
                        }
                    }
                    else {
                        createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
                    }
                }
            }
            if (!options.sourceMap && !options.inlineSourceMap) {
                if (options.inlineSources) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
                }
                if (options.sourceRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
                }
            }
            if (options.out && options.outFile) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
            }
            if (options.mapRoot && !options.sourceMap) {
                // Error to specify --mapRoot without --sourcemap
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap");
            }
            if (options.declarationDir) {
                if (!options.declaration) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration");
                }
                if (options.out || options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
                }
            }
            if (options.lib && options.noLib) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
            }
            if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
            }
            var languageVersion = options.target || 0 /* ES3 */;
            var outFile = options.outFile || options.out;
            var firstNonAmbientExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) && !f.isDeclarationFile ? f : undefined; });
            if (options.isolatedModules) {
                if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES2015 */) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
                }
                var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !f.isDeclarationFile ? f : undefined; });
                if (firstNonExternalModuleSourceFile) {
                    var span_7 = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span_7.start, span_7.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
                }
            }
            else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === ts.ModuleKind.None) {
                // We cannot use createDiagnosticFromNode because nodes do not have parents yet
                var span_8 = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span_8.start, span_8.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
            }
            // Cannot specify module gen that isn't amd or system with --out
            if (outFile) {
                if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
                }
                else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
                    var span_9 = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span_9.start, span_9.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile"));
                }
            }
            // there has to be common source directory if user specified --outdir || --sourceRoot
            // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
            if (options.outDir || // there is --outDir specified
                options.sourceRoot || // there is --sourceRoot specified
                options.mapRoot) {
                // Precalculate and cache the common source directory
                var dir = getCommonSourceDirectory();
                // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
                if (options.outDir && dir === "" && ts.forEach(files, function (file) { return ts.getRootLength(file.fileName) > 1; })) {
                    createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
                }
            }
            if (!options.noEmit && options.allowJs && options.declaration) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration");
            }
            if (options.checkJs && !options.allowJs) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
            }
            if (options.emitDecoratorMetadata &&
                !options.experimentalDecorators) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
            }
            if (options.jsxFactory) {
                if (options.reactNamespace) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
                }
                if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
                    createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
                }
            }
            else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) {
                createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
            }
            // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
            if (!options.noEmit && !options.suppressOutputPathCheck) {
                var emitHost = getEmitHost();
                var emitFilesSeen_1 = ts.createMap();
                ts.forEachEmittedFile(emitHost, function (emitFileNames) {
                    verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen_1);
                    verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen_1);
                });
            }
            // Verify that all the emit files are unique and don't overwrite input files
            function verifyEmitFilePath(emitFileName, emitFilesSeen) {
                if (emitFileName) {
                    var emitFilePath = toPath(emitFileName);
                    // Report error if the output overwrites input file
                    if (filesByName.has(emitFilePath)) {
                        var chain_1;
                        if (!options.configFilePath) {
                            // The program is from either an inferred project or an external project
                            chain_1 = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
                        }
                        chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain_1));
                    }
                    var emitFileKey = !host.useCaseSensitiveFileNames() ? emitFilePath.toLocaleLowerCase() : emitFilePath;
                    // Report error if multiple files write into same file
                    if (emitFilesSeen.has(emitFileKey)) {
                        // Already seen the same emit file - report error
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
                    }
                    else {
                        emitFilesSeen.set(emitFileKey, true);
                    }
                }
            }
        }
        function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, arg0, arg1, arg2) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_1 = pathsSyntax; _i < pathsSyntax_1.length; _i++) {
                var pathProp = pathsSyntax_1[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer)) {
                    for (var _a = 0, _b = ts.getPropertyAssignment(pathProp.initializer, key); _a < _b.length; _a++) {
                        var keyProps = _b[_a];
                        if (ts.isArrayLiteralExpression(keyProps.initializer) &&
                            keyProps.initializer.elements.length > valueIndex) {
                            programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, keyProps.initializer.elements[valueIndex], message, arg0, arg1, arg2));
                            needCompilerDiagnostic = false;
                        }
                    }
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function createDiagnosticForOptionPaths(onKey, key, message, arg0) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_2 = pathsSyntax; _i < pathsSyntax_2.length; _i++) {
                var pathProp = pathsSyntax_2[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer) &&
                    createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) {
                    needCompilerDiagnostic = false;
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0));
            }
        }
        function getOptionPathsSyntax() {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            if (compilerOptionsObjectLiteralSyntax) {
                return ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, "paths");
            }
            return ts.emptyArray;
        }
        function createDiagnosticForOptionName(message, option1, option2) {
            createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2);
        }
        function createOptionValueDiagnostic(option1, message, arg0) {
            createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
        }
        function createDiagnosticForOption(onKey, option1, option2, message, arg0, arg1) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            var needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
                !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1);
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
        function getCompilerOptionsObjectLiteralSyntax() {
            if (_compilerOptionsObjectLiteralSyntax === undefined) {
                _compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
                if (options.configFile && options.configFile.jsonObject) {
                    for (var _i = 0, _a = ts.getPropertyAssignment(options.configFile.jsonObject, "compilerOptions"); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        if (ts.isObjectLiteralExpression(prop.initializer)) {
                            _compilerOptionsObjectLiteralSyntax = prop.initializer;
                            break;
                        }
                    }
                }
            }
            return _compilerOptionsObjectLiteralSyntax;
        }
        function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, arg0, arg1) {
            var props = ts.getPropertyAssignment(objectLiteral, key1, key2);
            for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
                var prop = props_2[_i];
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1));
            }
            return !!props.length;
        }
        function blockEmittingOfFile(emitFileName, diag) {
            hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
            programDiagnostics.add(diag);
        }
    }
    ts.createProgram = createProgram;
    /* @internal */
    /**
     * Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
     * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
     * This returns a diagnostic even if the module will be an untyped module.
     */
    function getResolutionDiagnostic(options, _a) {
        var extension = _a.extension;
        switch (extension) {
            case ".ts" /* Ts */:
            case ".d.ts" /* Dts */:
                // These are always allowed.
                return undefined;
            case ".tsx" /* Tsx */:
                return needJsx();
            case ".jsx" /* Jsx */:
                return needJsx() || needAllowJs();
            case ".js" /* Js */:
                return needAllowJs();
        }
        function needJsx() {
            return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
        }
        function needAllowJs() {
            return options.allowJs || !options.noImplicitAny ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
        }
    }
    ts.getResolutionDiagnostic = getResolutionDiagnostic;
    function checkAllDefined(names) {
        ts.Debug.assert(names.every(function (name) { return name !== undefined; }), "A name is undefined.", function () { return JSON.stringify(names); });
        return names;
    }
    function getModuleNames(_a) {
        var imports = _a.imports, moduleAugmentations = _a.moduleAugmentations;
        var res = imports.map(function (i) { return i.text; });
        for (var _i = 0, moduleAugmentations_1 = moduleAugmentations; _i < moduleAugmentations_1.length; _i++) {
            var aug = moduleAugmentations_1[_i];
            if (aug.kind === 9 /* StringLiteral */) {
                res.push(aug.text);
            }
            // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
        }
        return res;
    }
})(ts || (ts = {}));
/// <reference path="sys.ts"/>
/// <reference path="types.ts"/>
/// <reference path="core.ts"/>
/// <reference path="diagnosticInformationMap.generated.ts"/>
/// <reference path="parser.ts"/>
var ts;
(function (ts) {
    /* @internal */
    ts.compileOnSaveCommandLineOption = { name: "compileOnSave", type: "boolean" };
    /* @internal */
    ts.optionDeclarations = [
        // CommandLine only options
        {
            name: "help",
            shortName: "h",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_this_message,
        },
        {
            name: "help",
            shortName: "?",
            type: "boolean"
        },
        {
            name: "all",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_all_compiler_options,
        },
        {
            name: "version",
            shortName: "v",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_the_compiler_s_version,
        },
        {
            name: "init",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file,
        },
        {
            name: "project",
            shortName: "p",
            type: "string",
            isFilePath: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
            description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json,
        },
        {
            name: "pretty",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
        },
        {
            name: "watch",
            shortName: "w",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Watch_input_files,
        },
        // Basic
        {
            name: "target",
            shortName: "t",
            type: ts.createMapFromTemplate({
                "es3": 0 /* ES3 */,
                "es5": 1 /* ES5 */,
                "es6": 2 /* ES2015 */,
                "es2015": 2 /* ES2015 */,
                "es2016": 3 /* ES2016 */,
                "es2017": 4 /* ES2017 */,
                "esnext": 5 /* ESNext */,
            }),
            paramType: ts.Diagnostics.VERSION,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT,
        },
        {
            name: "module",
            shortName: "m",
            type: ts.createMapFromTemplate({
                "none": ts.ModuleKind.None,
                "commonjs": ts.ModuleKind.CommonJS,
                "amd": ts.ModuleKind.AMD,
                "system": ts.ModuleKind.System,
                "umd": ts.ModuleKind.UMD,
                "es6": ts.ModuleKind.ES2015,
                "es2015": ts.ModuleKind.ES2015,
                "esnext": ts.ModuleKind.ESNext
            }),
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext,
        },
        {
            name: "lib",
            type: "list",
            element: {
                name: "lib",
                type: ts.createMapFromTemplate({
                    // JavaScript only
                    "es5": "lib.es5.d.ts",
                    "es6": "lib.es2015.d.ts",
                    "es2015": "lib.es2015.d.ts",
                    "es7": "lib.es2016.d.ts",
                    "es2016": "lib.es2016.d.ts",
                    "es2017": "lib.es2017.d.ts",
                    "esnext": "lib.esnext.d.ts",
                    // Host only
                    "dom": "lib.dom.d.ts",
                    "dom.iterable": "lib.dom.iterable.d.ts",
                    "webworker": "lib.webworker.d.ts",
                    "scripthost": "lib.scripthost.d.ts",
                    // ES2015 Or ESNext By-feature options
                    "es2015.core": "lib.es2015.core.d.ts",
                    "es2015.collection": "lib.es2015.collection.d.ts",
                    "es2015.generator": "lib.es2015.generator.d.ts",
                    "es2015.iterable": "lib.es2015.iterable.d.ts",
                    "es2015.promise": "lib.es2015.promise.d.ts",
                    "es2015.proxy": "lib.es2015.proxy.d.ts",
                    "es2015.reflect": "lib.es2015.reflect.d.ts",
                    "es2015.symbol": "lib.es2015.symbol.d.ts",
                    "es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts",
                    "es2016.array.include": "lib.es2016.array.include.d.ts",
                    "es2017.object": "lib.es2017.object.d.ts",
                    "es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
                    "es2017.string": "lib.es2017.string.d.ts",
                    "es2017.intl": "lib.es2017.intl.d.ts",
                    "esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
                }),
            },
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
        },
        {
            name: "allowJs",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Allow_javascript_files_to_be_compiled
        },
        {
            name: "checkJs",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Report_errors_in_js_files
        },
        {
            name: "jsx",
            type: ts.createMapFromTemplate({
                "preserve": 1 /* Preserve */,
                "react-native": 3 /* ReactNative */,
                "react": 2 /* React */
            }),
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react,
        },
        {
            name: "declaration",
            shortName: "d",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_d_ts_file,
        },
        {
            name: "sourceMap",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_map_file,
        },
        {
            name: "outFile",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file,
        },
        {
            name: "outDir",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Redirect_output_structure_to_the_directory,
        },
        {
            name: "rootDir",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
        },
        {
            name: "removeComments",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_comments_to_output,
        },
        {
            name: "noEmit",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_outputs,
        },
        {
            name: "importHelpers",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Import_emit_helpers_from_tslib
        },
        {
            name: "downlevelIteration",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3
        },
        {
            name: "isolatedModules",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule
        },
        // Strict Type Checks
        {
            name: "strict",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_all_strict_type_checking_options
        },
        {
            name: "noImplicitAny",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type,
        },
        {
            name: "strictNullChecks",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_null_checks
        },
        {
            name: "strictFunctionTypes",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_function_types
        },
        {
            name: "noImplicitThis",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
        },
        {
            name: "alwaysStrict",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
        },
        // Additional Checks
        {
            name: "noUnusedLocals",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_locals,
        },
        {
            name: "noUnusedParameters",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_parameters,
        },
        {
            name: "noImplicitReturns",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
        },
        {
            name: "noFallthroughCasesInSwitch",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
        },
        // Module Resolution
        {
            name: "moduleResolution",
            type: ts.createMapFromTemplate({
                "node": ts.ModuleResolutionKind.NodeJs,
                "classic": ts.ModuleResolutionKind.Classic,
            }),
            paramType: ts.Diagnostics.STRATEGY,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
        },
        {
            name: "baseUrl",
            type: "string",
            isFilePath: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Base_directory_to_resolve_non_absolute_module_names
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "paths",
            type: "object",
            isTSConfigOnly: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "rootDirs",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "rootDirs",
                type: "string",
                isFilePath: true
            },
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime
        },
        {
            name: "typeRoots",
            type: "list",
            element: {
                name: "typeRoots",
                type: "string",
                isFilePath: true
            },
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_folders_to_include_type_definitions_from
        },
        {
            name: "types",
            type: "list",
            element: {
                name: "types",
                type: "string"
            },
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation
        },
        {
            name: "allowSyntheticDefaultImports",
            type: "boolean",
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
        },
        {
            name: "preserveSymlinks",
            type: "boolean",
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks,
        },
        // Source Maps
        {
            name: "sourceRoot",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
        },
        {
            name: "mapRoot",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
        },
        {
            name: "inlineSourceMap",
            type: "boolean",
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file
        },
        {
            name: "inlineSources",
            type: "boolean",
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set
        },
        // Experimental
        {
            name: "experimentalDecorators",
            type: "boolean",
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators
        },
        {
            name: "emitDecoratorMetadata",
            type: "boolean",
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
        },
        // Advanced
        {
            name: "jsxFactory",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
        },
        {
            name: "diagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_diagnostic_information
        },
        {
            name: "extendedDiagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_verbose_diagnostic_information
        },
        {
            name: "traceResolution",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process
        },
        {
            name: "listFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_files_part_of_the_compilation
        },
        {
            name: "listEmittedFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_generated_files_part_of_the_compilation
        },
        {
            name: "out",
            type: "string",
            isFilePath: false,
            // for correct behaviour, please use outFile
            category: ts.Diagnostics.Advanced_Options,
            paramType: ts.Diagnostics.FILE,
            description: ts.Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file,
        },
        {
            name: "reactNamespace",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit
        },
        {
            name: "skipDefaultLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files
        },
        {
            name: "charset",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_character_set_of_the_input_files
        },
        {
            name: "emitBOM",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
        },
        {
            name: "locale",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
        },
        {
            name: "newLine",
            type: ts.createMapFromTemplate({
                "crlf": 0 /* CarriageReturnLineFeed */,
                "lf": 1 /* LineFeed */
            }),
            paramType: ts.Diagnostics.NEWLINE,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
        },
        {
            name: "noErrorTruncation",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_truncate_error_messages
        },
        {
            name: "noLib",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_include_the_default_library_file_lib_d_ts
        },
        {
            name: "noResolve",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files
        },
        {
            name: "stripInternal",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
        },
        {
            name: "disableSizeLimit",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_size_limitations_on_JavaScript_projects
        },
        {
            name: "noImplicitUseStrict",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output
        },
        {
            name: "noEmitHelpers",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output
        },
        {
            name: "noEmitOnError",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
        },
        {
            name: "preserveConstEnums",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
        },
        {
            name: "declarationDir",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Output_directory_for_generated_declaration_files
        },
        {
            name: "skipLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Skip_type_checking_of_declaration_files,
        },
        {
            name: "allowUnusedLabels",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unused_labels
        },
        {
            name: "allowUnreachableCode",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code
        },
        {
            name: "suppressExcessPropertyErrors",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals,
        },
        {
            name: "suppressImplicitAnyIndexErrors",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures,
        },
        {
            name: "forceConsistentCasingInFileNames",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
        },
        {
            name: "maxNodeModuleJsDepth",
            type: "number",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
        },
        {
            name: "noStrictGenericChecks",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
        },
        {
            // A list of plugins to load in the language service
            name: "plugins",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "plugin",
                type: "object"
            },
            description: ts.Diagnostics.List_of_language_service_plugins
        }
    ];
    /* @internal */
    ts.typeAcquisitionDeclarations = [
        {
            /* @deprecated typingOptions.enableAutoDiscovery
             * Use typeAcquisition.enable instead.
             */
            name: "enableAutoDiscovery",
            type: "boolean",
        },
        {
            name: "enable",
            type: "boolean",
        },
        {
            name: "include",
            type: "list",
            element: {
                name: "include",
                type: "string"
            }
        },
        {
            name: "exclude",
            type: "list",
            element: {
                name: "exclude",
                type: "string"
            }
        }
    ];
    /* @internal */
    ts.defaultInitCompilerOptions = {
        module: ts.ModuleKind.CommonJS,
        target: 1 /* ES5 */,
        strict: true
    };
    var optionNameMapCache;
    /* @internal */
    function convertEnableAutoDiscoveryToEnable(typeAcquisition) {
        // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable
        if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) {
            var result = {
                enable: typeAcquisition.enableAutoDiscovery,
                include: typeAcquisition.include || [],
                exclude: typeAcquisition.exclude || []
            };
            return result;
        }
        return typeAcquisition;
    }
    ts.convertEnableAutoDiscoveryToEnable = convertEnableAutoDiscoveryToEnable;
    function getOptionNameMap() {
        if (optionNameMapCache) {
            return optionNameMapCache;
        }
        var optionNameMap = ts.createMap();
        var shortOptionNames = ts.createMap();
        ts.forEach(ts.optionDeclarations, function (option) {
            optionNameMap.set(option.name.toLowerCase(), option);
            if (option.shortName) {
                shortOptionNames.set(option.shortName, option.name);
            }
        });
        optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames };
        return optionNameMapCache;
    }
    /* @internal */
    function createCompilerDiagnosticForInvalidCustomType(opt) {
        return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic);
    }
    ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType;
    function createDiagnosticForInvalidCustomType(opt, createDiagnostic) {
        var namesOfType = ts.arrayFrom(opt.type.keys()).map(function (key) { return "'" + key + "'"; }).join(", ");
        return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType);
    }
    /* @internal */
    function parseCustomTypeOption(opt, value, errors) {
        return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
    }
    ts.parseCustomTypeOption = parseCustomTypeOption;
    /* @internal */
    function parseListTypeOption(opt, value, errors) {
        if (value === void 0) { value = ""; }
        value = trimString(value);
        if (ts.startsWith(value, "-")) {
            return undefined;
        }
        if (value === "") {
            return [];
        }
        var values = value.split(",");
        switch (opt.element.type) {
            case "number":
                return ts.map(values, parseInt);
            case "string":
                return ts.map(values, function (v) { return v || ""; });
            default:
                return ts.filter(ts.map(values, function (v) { return parseCustomTypeOption(opt.element, v, errors); }), function (v) { return !!v; });
        }
    }
    ts.parseListTypeOption = parseListTypeOption;
    function parseCommandLine(commandLine, readFile) {
        var options = {};
        var fileNames = [];
        var errors = [];
        parseStrings(commandLine);
        return {
            options: options,
            fileNames: fileNames,
            errors: errors
        };
        function parseStrings(args) {
            var i = 0;
            while (i < args.length) {
                var s = args[i];
                i++;
                if (s.charCodeAt(0) === 64 /* at */) {
                    parseResponseFile(s.slice(1));
                }
                else if (s.charCodeAt(0) === 45 /* minus */) {
                    var opt = getOptionFromName(s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1), /*allowShort*/ true);
                    if (opt) {
                        if (opt.isTSConfigOnly) {
                            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
                        }
                        else {
                            // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
                            if (!args[i] && opt.type !== "boolean") {
                                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
                            }
                            switch (opt.type) {
                                case "number":
                                    options[opt.name] = parseInt(args[i]);
                                    i++;
                                    break;
                                case "boolean":
                                    // boolean flag has optional value true, false, others
                                    var optValue = args[i];
                                    options[opt.name] = optValue !== "false";
                                    // consume next argument as boolean flag value
                                    if (optValue === "false" || optValue === "true") {
                                        i++;
                                    }
                                    break;
                                case "string":
                                    options[opt.name] = args[i] || "";
                                    i++;
                                    break;
                                case "list":
                                    var result = parseListTypeOption(opt, args[i], errors);
                                    options[opt.name] = result || [];
                                    if (result) {
                                        i++;
                                    }
                                    break;
                                // If not a primitive, the possible types are specified in what is effectively a map of options.
                                default:
                                    options[opt.name] = parseCustomTypeOption(opt, args[i], errors);
                                    i++;
                                    break;
                            }
                        }
                    }
                    else {
                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_compiler_option_0, s));
                    }
                }
                else {
                    fileNames.push(s);
                }
            }
        }
        function parseResponseFile(fileName) {
            var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName);
            if (!text) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName));
                return;
            }
            var args = [];
            var pos = 0;
            while (true) {
                while (pos < text.length && text.charCodeAt(pos) <= 32 /* space */)
                    pos++;
                if (pos >= text.length)
                    break;
                var start = pos;
                if (text.charCodeAt(start) === 34 /* doubleQuote */) {
                    pos++;
                    while (pos < text.length && text.charCodeAt(pos) !== 34 /* doubleQuote */)
                        pos++;
                    if (pos < text.length) {
                        args.push(text.substring(start + 1, pos));
                        pos++;
                    }
                    else {
                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName));
                    }
                }
                else {
                    while (text.charCodeAt(pos) > 32 /* space */)
                        pos++;
                    args.push(text.substring(start, pos));
                }
            }
            parseStrings(args);
        }
    }
    ts.parseCommandLine = parseCommandLine;
    function getOptionFromName(optionName, allowShort) {
        if (allowShort === void 0) { allowShort = false; }
        optionName = optionName.toLowerCase();
        var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames;
        // Try to translate short option names to their full equivalents.
        if (allowShort) {
            var short = shortOptionNames.get(optionName);
            if (short !== undefined) {
                optionName = short;
            }
        }
        return optionNameMap.get(optionName);
    }
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
    }
    ts.readConfigFile = readConfigFile;
    /**
     * Parse the text of the tsconfig.json file
     * @param fileName The path to the config file
     * @param jsonText The text of the config file
     */
    function parseConfigFileTextToJson(fileName, jsonText) {
        var jsonSourceFile = ts.parseJsonText(fileName, jsonText);
        return {
            config: convertToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics),
            error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
        };
    }
    ts.parseConfigFileTextToJson = parseConfigFileTextToJson;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readJsonConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] };
    }
    ts.readJsonConfigFile = readJsonConfigFile;
    function tryReadFile(fileName, readFile) {
        var text;
        try {
            text = readFile(fileName);
        }
        catch (e) {
            return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
        }
        return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text;
    }
    function commandLineOptionsToMap(options) {
        return ts.arrayToMap(options, function (option) { return option.name; });
    }
    var _tsconfigRootOptions;
    function getTsconfigRootOptionsMap() {
        if (_tsconfigRootOptions === undefined) {
            _tsconfigRootOptions = commandLineOptionsToMap([
                {
                    name: "compilerOptions",
                    type: "object",
                    elementOptions: commandLineOptionsToMap(ts.optionDeclarations),
                    extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_compiler_option_0
                },
                {
                    name: "typingOptions",
                    type: "object",
                    elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations),
                    extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0
                },
                {
                    name: "typeAcquisition",
                    type: "object",
                    elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations),
                    extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0
                },
                {
                    name: "extends",
                    type: "string"
                },
                {
                    name: "files",
                    type: "list",
                    element: {
                        name: "files",
                        type: "string"
                    }
                },
                {
                    name: "include",
                    type: "list",
                    element: {
                        name: "include",
                        type: "string"
                    }
                },
                {
                    name: "exclude",
                    type: "list",
                    element: {
                        name: "exclude",
                        type: "string"
                    }
                },
                ts.compileOnSaveCommandLineOption
            ]);
        }
        return _tsconfigRootOptions;
    }
    /**
     * Convert the json syntax tree into the json value
     */
    function convertToObject(sourceFile, errors) {
        return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
    }
    ts.convertToObject = convertToObject;
    /**
     * Convert the json syntax tree into the json value
     */
    function convertToObjectWorker(sourceFile, errors, knownRootOptions, jsonConversionNotifier) {
        if (!sourceFile.jsonObject) {
            return {};
        }
        return convertObjectLiteralExpressionToJson(sourceFile.jsonObject, knownRootOptions, 
        /*extraKeyDiagnosticMessage*/ undefined, /*parentOption*/ undefined);
        function convertObjectLiteralExpressionToJson(node, knownOptions, extraKeyDiagnosticMessage, parentOption) {
            var result = {};
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var element = _a[_i];
                if (element.kind !== 261 /* PropertyAssignment */) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected));
                    continue;
                }
                if (element.questionToken) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
                }
                if (!isDoubleQuotedString(element.name)) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected));
                }
                var keyText = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(element.name));
                var option = knownOptions ? knownOptions.get(keyText) : undefined;
                if (extraKeyDiagnosticMessage && !option) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
                }
                var value = convertPropertyValueToJson(element.initializer, option);
                if (typeof keyText !== "undefined") {
                    result[keyText] = value;
                    // Notify key value set, if user asked for it
                    if (jsonConversionNotifier &&
                        // Current callbacks are only on known parent option or if we are setting values in the root
                        (parentOption || knownOptions === knownRootOptions)) {
                        var isValidOptionValue = isCompilerOptionsValue(option, value);
                        if (parentOption) {
                            if (isValidOptionValue) {
                                // Notify option set in the parent if its a valid option value
                                jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value);
                            }
                        }
                        else if (knownOptions === knownRootOptions) {
                            if (isValidOptionValue) {
                                // Notify about the valid root key value being set
                                jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                            else if (!option) {
                                // Notify about the unknown root key value being set
                                jsonConversionNotifier.onSetUnknownOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                        }
                    }
                }
            }
            return result;
        }
        function convertArrayLiteralExpressionToJson(elements, elementOption) {
            return elements.map(function (element) { return convertPropertyValueToJson(element, elementOption); });
        }
        function convertPropertyValueToJson(valueExpression, option) {
            switch (valueExpression.kind) {
                case 101 /* TrueKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return true;
                case 86 /* FalseKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return false;
                case 95 /* NullKeyword */:
                    reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
                    return null; // tslint:disable-line:no-null-keyword
                case 9 /* StringLiteral */:
                    if (!isDoubleQuotedString(valueExpression)) {
                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected));
                    }
                    reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string"));
                    var text = valueExpression.text;
                    if (option && !ts.isString(option.type)) {
                        var customOption = option;
                        // Validate custom option type
                        if (!customOption.type.has(text.toLowerCase())) {
                            errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); }));
                        }
                    }
                    return text;
                case 8 /* NumericLiteral */:
                    reportInvalidOptionValue(option && option.type !== "number");
                    return Number(valueExpression.text);
                case 178 /* ObjectLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "object");
                    var objectLiteralExpression = valueExpression;
                    // Currently having element option declaration in the tsconfig with type "object"
                    // determines if it needs onSetValidOptionKeyValueInParent callback or not
                    // At moment there are only "compilerOptions", "typeAcquisition" and "typingOptions"
                    // that satifies it and need it to modify options set in them (for normalizing file paths)
                    // vs what we set in the json
                    // If need arises, we can modify this interface and callbacks as needed
                    if (option) {
                        var _a = option, elementOptions = _a.elementOptions, extraKeyDiagnosticMessage = _a.extraKeyDiagnosticMessage, optionName = _a.name;
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnosticMessage, optionName);
                    }
                    else {
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, 
                        /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined);
                    }
                case 177 /* ArrayLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "list");
                    return convertArrayLiteralExpressionToJson(valueExpression.elements, option && option.element);
            }
            // Not in expected format
            if (option) {
                reportInvalidOptionValue(/*isError*/ true);
            }
            else {
                errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal));
            }
            return undefined;
            function reportInvalidOptionValue(isError) {
                if (isError) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option)));
                }
            }
        }
        function isDoubleQuotedString(node) {
            return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile);
        }
    }
    function getCompilerOptionValueTypeString(option) {
        return option.type === "list" ?
            "Array" :
            ts.isString(option.type) ? option.type : "string";
    }
    function isCompilerOptionsValue(option, value) {
        if (option) {
            if (isNullOrUndefined(value))
                return true; // All options are undefinable/nullable
            if (option.type === "list") {
                return ts.isArray(value);
            }
            var expectedType = ts.isString(option.type) ? option.type : "string";
            return typeof value === expectedType;
        }
    }
    /**
     * Generate tsconfig configuration when running command line "--init"
     * @param options commandlineOptions to be generated into tsconfig.json
     * @param fileNames array of filenames to be generated into tsconfig.json
     */
    /* @internal */
    function generateTSConfig(options, fileNames, newLine) {
        var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions);
        var compilerOptionsMap = serializeCompilerOptions(compilerOptions);
        return writeConfigurations();
        function getCustomTypeMapOfCommandLineOption(optionDefinition) {
            if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
                // this is of a type CommandLineOptionOfPrimitiveType
                return undefined;
            }
            else if (optionDefinition.type === "list") {
                return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
            }
            else {
                return optionDefinition.type;
            }
        }
        function getNameOfCompilerOptionValue(value, customTypeMap) {
            // There is a typeMap associated with this command-line option so use it to map value back to its name
            return ts.forEachEntry(customTypeMap, function (mapValue, key) {
                if (mapValue === value) {
                    return key;
                }
            });
        }
        function serializeCompilerOptions(options) {
            var result = ts.createMap();
            var optionsNameMap = getOptionNameMap().optionNameMap;
            var _loop_5 = function (name) {
                if (ts.hasProperty(options, name)) {
                    // tsconfig only options cannot be specified via command line,
                    // so we can assume that only types that can appear here string | number | boolean
                    if (optionsNameMap.has(name) && optionsNameMap.get(name).category === ts.Diagnostics.Command_line_Options) {
                        return "continue";
                    }
                    var value = options[name];
                    var optionDefinition = optionsNameMap.get(name.toLowerCase());
                    if (optionDefinition) {
                        var customTypeMap_1 = getCustomTypeMapOfCommandLineOption(optionDefinition);
                        if (!customTypeMap_1) {
                            // There is no map associated with this compiler option then use the value as-is
                            // This is the case if the value is expect to be string, number, boolean or list of string
                            result.set(name, value);
                        }
                        else {
                            if (optionDefinition.type === "list") {
                                result.set(name, value.map(function (element) { return getNameOfCompilerOptionValue(element, customTypeMap_1); }));
                            }
                            else {
                                // There is a typeMap associated with this command-line option so use it to map value back to its name
                                result.set(name, getNameOfCompilerOptionValue(value, customTypeMap_1));
                            }
                        }
                    }
                }
            };
            for (var name in options) {
                _loop_5(name);
            }
            return result;
        }
        function getDefaultValueForOption(option) {
            switch (option.type) {
                case "number":
                    return 1;
                case "boolean":
                    return true;
                case "string":
                    return option.isFilePath ? "./" : "";
                case "list":
                    return [];
                case "object":
                    return {};
                default:
                    return option.type.keys().next().value;
            }
        }
        function makePadding(paddingLength) {
            return Array(paddingLength + 1).join(" ");
        }
        function writeConfigurations() {
            // Filter applicable options to place in the file
            var categorizedOptions = ts.createMultiMap();
            for (var _i = 0, optionDeclarations_1 = ts.optionDeclarations; _i < optionDeclarations_1.length; _i++) {
                var option = optionDeclarations_1[_i];
                var category = option.category;
                if (category !== undefined && category !== ts.Diagnostics.Command_line_Options && category !== ts.Diagnostics.Advanced_Options) {
                    categorizedOptions.add(ts.getLocaleSpecificMessage(category), option);
                }
            }
            // Serialize all options and their descriptions
            var marginLength = 0;
            var seenKnownKeys = 0;
            var nameColumn = [];
            var descriptionColumn = [];
            categorizedOptions.forEach(function (options, category) {
                if (nameColumn.length !== 0) {
                    nameColumn.push("");
                    descriptionColumn.push("");
                }
                nameColumn.push("/* " + category + " */");
                descriptionColumn.push("");
                for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
                    var option = options_1[_i];
                    var optionName = void 0;
                    if (compilerOptionsMap.has(option.name)) {
                        optionName = "\"" + option.name + "\": " + JSON.stringify(compilerOptionsMap.get(option.name)) + ((seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ",");
                    }
                    else {
                        optionName = "// \"" + option.name + "\": " + JSON.stringify(getDefaultValueForOption(option)) + ",";
                    }
                    nameColumn.push(optionName);
                    descriptionColumn.push("/* " + (option.description && ts.getLocaleSpecificMessage(option.description) || option.name) + " */");
                    marginLength = Math.max(optionName.length, marginLength);
                }
            });
            // Write the output
            var tab = makePadding(2);
            var result = [];
            result.push("{");
            result.push(tab + "\"compilerOptions\": {");
            // Print out each row, aligning all the descriptions on the same column.
            for (var i = 0; i < nameColumn.length; i++) {
                var optionName = nameColumn[i];
                var description = descriptionColumn[i];
                result.push(optionName && "" + tab + tab + optionName + (description && (makePadding(marginLength - optionName.length + 2) + description)));
            }
            if (fileNames.length) {
                result.push(tab + "},");
                result.push(tab + "\"files\": [");
                for (var i = 0; i < fileNames.length; i++) {
                    result.push("" + tab + tab + JSON.stringify(fileNames[i]) + (i === fileNames.length - 1 ? "" : ","));
                }
                result.push(tab + "]");
            }
            else {
                result.push(tab + "}");
            }
            result.push("}");
            return result.join(newLine);
        }
    }
    ts.generateTSConfig = generateTSConfig;
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) {
        return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
    }
    ts.parseJsonConfigFileContent = parseJsonConfigFileContent;
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param jsonNode The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonSourceFileConfigFileContent(sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) {
        return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
    }
    ts.parseJsonSourceFileConfigFileContent = parseJsonSourceFileConfigFileContent;
    /*@internal*/
    function setConfigFileInOptions(options, configFile) {
        if (configFile) {
            Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
        }
    }
    ts.setConfigFileInOptions = setConfigFileInOptions;
    function isNullOrUndefined(x) {
        // tslint:disable-next-line:no-null-keyword
        return x === undefined || x === null;
    }
    function directoryOfCombinedPath(fileName, basePath) {
        // Use the `identity` function to avoid canonicalizing the path, as it must remain noncanonical
        // until consistient casing errors are reported
        return ts.getDirectoryPath(ts.toPath(fileName, basePath, ts.identity));
    }
    /**
     * Parse the contents of a config file from json or json source file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param sourceFile sourceFile corresponding to the Json
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     * @param resolutionStack Only present for backwards-compatibility. Should be empty.
     */
    function parseJsonConfigFileContentWorker(json, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) {
        if (existingOptions === void 0) { existingOptions = {}; }
        if (resolutionStack === void 0) { resolutionStack = []; }
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
        var errors = [];
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        var parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors);
        var raw = parsedConfig.raw;
        var options = ts.extend(existingOptions, parsedConfig.options || {});
        options.configFilePath = configFileName;
        setConfigFileInOptions(options, sourceFile);
        var _a = getFileNames(), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories, spec = _a.spec;
        return {
            options: options,
            fileNames: fileNames,
            typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
            raw: raw,
            errors: errors,
            wildcardDirectories: wildcardDirectories,
            compileOnSave: !!raw.compileOnSave,
            configFileSpecs: spec
        };
        function getFileNames() {
            var filesSpecs;
            if (ts.hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
                if (ts.isArray(raw.files)) {
                    filesSpecs = raw.files;
                    if (filesSpecs.length === 0) {
                        createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array");
                }
            }
            var includeSpecs;
            if (ts.hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
                if (ts.isArray(raw.include)) {
                    includeSpecs = raw.include;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
                }
            }
            var excludeSpecs;
            if (ts.hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
                if (ts.isArray(raw.exclude)) {
                    excludeSpecs = raw.exclude;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
                }
            }
            else {
                var outDir = raw.compilerOptions && raw.compilerOptions.outDir;
                if (outDir) {
                    excludeSpecs = [outDir];
                }
            }
            if (filesSpecs === undefined && includeSpecs === undefined) {
                includeSpecs = ["**/*"];
            }
            var result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
            if (result.fileNames.length === 0 && !ts.hasProperty(raw, "files") && resolutionStack.length === 0) {
                errors.push(getErrorForNoInputFiles(result.spec, configFileName));
            }
            return result;
        }
        function createCompilerDiagnosticOnlyIfJson(message, arg0, arg1) {
            if (!sourceFile) {
                errors.push(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
    }
    /*@internal*/
    function isErrorNoInputFiles(error) {
        return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
    }
    ts.isErrorNoInputFiles = isErrorNoInputFiles;
    /*@internal*/
    function getErrorForNoInputFiles(_a, configFileName) {
        var includeSpecs = _a.includeSpecs, excludeSpecs = _a.excludeSpecs;
        return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || []));
    }
    ts.getErrorForNoInputFiles = getErrorForNoInputFiles;
    function isSuccessfulParsedTsconfig(value) {
        return !!value.options;
    }
    /**
     * This *just* extracts options/include/exclude/files out of a config file.
     * It does *not* resolve the included files.
     */
    function parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors) {
        basePath = ts.normalizeSlashes(basePath);
        var resolvedPath = ts.toPath(configFileName || "", basePath, getCanonicalFileName);
        if (resolutionStack.indexOf(resolvedPath) >= 0) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, resolutionStack.concat([resolvedPath]).join(" -> ")));
            return { raw: json || convertToObject(sourceFile, errors) };
        }
        var ownConfig = json ?
            parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) :
            parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors);
        if (ownConfig.extendedConfigPath) {
            // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
            resolutionStack = resolutionStack.concat([resolvedPath]);
            var extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors);
            if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
                var baseRaw_1 = extendedConfig.raw;
                var raw_1 = ownConfig.raw;
                var setPropertyInRawIfNotUndefined = function (propertyName) {
                    var value = raw_1[propertyName] || baseRaw_1[propertyName];
                    if (value) {
                        raw_1[propertyName] = value;
                    }
                };
                setPropertyInRawIfNotUndefined("include");
                setPropertyInRawIfNotUndefined("exclude");
                setPropertyInRawIfNotUndefined("files");
                if (raw_1.compileOnSave === undefined) {
                    raw_1.compileOnSave = baseRaw_1.compileOnSave;
                }
                ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options);
                // TODO extend type typeAcquisition
            }
        }
        return ownConfig;
    }
    function parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) {
        if (ts.hasProperty(json, "excludes")) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
        }
        var options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName);
        // typingOptions has been deprecated and is only supported for backward compatibility purposes.
        // It should be removed in future releases - use typeAcquisition instead.
        var typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
        json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
        var extendedConfigPath;
        if (json.extends) {
            if (!ts.isString(json.extends)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
            }
            else {
                var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, getCanonicalFileName, errors, ts.createCompilerDiagnostic);
            }
        }
        return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors) {
        var options = getDefaultCompilerOptions(configFileName);
        var typeAcquisition, typingOptionstypeAcquisition;
        var extendedConfigPath;
        var optionsIterator = {
            onSetValidOptionKeyValueInParent: function (parentOption, option, value) {
                ts.Debug.assert(parentOption === "compilerOptions" || parentOption === "typeAcquisition" || parentOption === "typingOptions");
                var currentOption = parentOption === "compilerOptions" ?
                    options :
                    parentOption === "typeAcquisition" ?
                        (typeAcquisition || (typeAcquisition = getDefaultTypeAcquisition(configFileName))) :
                        (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName)));
                currentOption[option.name] = normalizeOptionValue(option, basePath, value);
            },
            onSetValidOptionKeyValueInRoot: function (key, _keyNode, value, valueNode) {
                switch (key) {
                    case "extends":
                        var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                        extendedConfigPath = getExtendsConfigPath(value, host, newBase, getCanonicalFileName, errors, function (message, arg0) {
                            return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0);
                        });
                        return;
                    case "files":
                        if (value.length === 0) {
                            errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
                        }
                        return;
                }
            },
            onSetUnknownOptionKeyValueInRoot: function (key, keyNode, _value, _valueNode) {
                if (key === "excludes") {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
                }
            }
        };
        var json = convertToObjectWorker(sourceFile, errors, getTsconfigRootOptionsMap(), optionsIterator);
        if (!typeAcquisition) {
            if (typingOptionstypeAcquisition) {
                typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
                    {
                        enable: typingOptionstypeAcquisition.enableAutoDiscovery,
                        include: typingOptionstypeAcquisition.include,
                        exclude: typingOptionstypeAcquisition.exclude
                    } :
                    typingOptionstypeAcquisition;
            }
            else {
                typeAcquisition = getDefaultTypeAcquisition(configFileName);
            }
        }
        return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function getExtendsConfigPath(extendedConfig, host, basePath, getCanonicalFileName, errors, createDiagnostic) {
        extendedConfig = ts.normalizeSlashes(extendedConfig);
        // If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
        if (!(ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../"))) {
            errors.push(createDiagnostic(ts.Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig));
            return undefined;
        }
        var extendedConfigPath = ts.toPath(extendedConfig, basePath, getCanonicalFileName);
        if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ".json" /* Json */)) {
            extendedConfigPath = extendedConfigPath + ".json";
            if (!host.fileExists(extendedConfigPath)) {
                errors.push(createDiagnostic(ts.Diagnostics.File_0_does_not_exist, extendedConfig));
                return undefined;
            }
        }
        return extendedConfigPath;
    }
    function getExtendedConfig(sourceFile, extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors) {
        var extendedResult = readJsonConfigFile(extendedConfigPath, function (path) { return host.readFile(path); });
        if (sourceFile) {
            (sourceFile.extendedSourceFiles || (sourceFile.extendedSourceFiles = [])).push(extendedResult.fileName);
        }
        if (extendedResult.parseDiagnostics.length) {
            errors.push.apply(errors, extendedResult.parseDiagnostics);
            return undefined;
        }
        var extendedDirname = ts.getDirectoryPath(extendedConfigPath);
        var extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, ts.getBaseFileName(extendedConfigPath), getCanonicalFileName, resolutionStack, errors);
        if (sourceFile) {
            (_a = sourceFile.extendedSourceFiles).push.apply(_a, extendedResult.extendedSourceFiles);
        }
        if (isSuccessfulParsedTsconfig(extendedConfig)) {
            // Update the paths to reflect base path
            var relativeDifference_1 = ts.convertToRelativePath(extendedDirname, basePath, getCanonicalFileName);
            var updatePath_1 = function (path) { return ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference_1, path); };
            var mapPropertiesInRawIfNotUndefined = function (propertyName) {
                if (raw_2[propertyName]) {
                    raw_2[propertyName] = ts.map(raw_2[propertyName], updatePath_1);
                }
            };
            var raw_2 = extendedConfig.raw;
            mapPropertiesInRawIfNotUndefined("include");
            mapPropertiesInRawIfNotUndefined("exclude");
            mapPropertiesInRawIfNotUndefined("files");
        }
        return extendedConfig;
        var _a;
    }
    function convertCompileOnSaveOptionFromJson(jsonOption, basePath, errors) {
        if (!ts.hasProperty(jsonOption, ts.compileOnSaveCommandLineOption.name)) {
            return undefined;
        }
        var result = convertJsonOption(ts.compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
        if (typeof result === "boolean" && result) {
            return result;
        }
        return false;
    }
    function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson;
    function convertTypeAcquisitionFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertTypeAcquisitionFromJson = convertTypeAcquisitionFromJson;
    function getDefaultCompilerOptions(configFileName) {
        var options = ts.getBaseFileName(configFileName) === "jsconfig.json"
            ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
            : {};
        return options;
    }
    function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultCompilerOptions(configFileName);
        convertOptionsFromJson(ts.optionDeclarations, jsonOptions, basePath, options, ts.Diagnostics.Unknown_compiler_option_0, errors);
        return options;
    }
    function getDefaultTypeAcquisition(configFileName) {
        var options = { enable: ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
        return options;
    }
    function convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultTypeAcquisition(configFileName);
        var typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
        convertOptionsFromJson(ts.typeAcquisitionDeclarations, typeAcquisition, basePath, options, ts.Diagnostics.Unknown_type_acquisition_option_0, errors);
        return options;
    }
    function convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, defaultOptions, diagnosticMessage, errors) {
        if (!jsonOptions) {
            return;
        }
        var optionNameMap = commandLineOptionsToMap(optionDeclarations);
        for (var id in jsonOptions) {
            var opt = optionNameMap.get(id);
            if (opt) {
                defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
            }
            else {
                errors.push(ts.createCompilerDiagnostic(diagnosticMessage, id));
            }
        }
    }
    function convertJsonOption(opt, value, basePath, errors) {
        if (isCompilerOptionsValue(opt, value)) {
            var optType = opt.type;
            if (optType === "list" && ts.isArray(value)) {
                return convertJsonOptionOfListType(opt, value, basePath, errors);
            }
            else if (!ts.isString(optType)) {
                return convertJsonOptionOfCustomType(opt, value, errors);
            }
            return normalizeNonListOptionValue(opt, basePath, value);
        }
        else {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt)));
        }
    }
    function normalizeOptionValue(option, basePath, value) {
        if (isNullOrUndefined(value))
            return undefined;
        if (option.type === "list") {
            var listOption_1 = option;
            if (listOption_1.element.isFilePath || !ts.isString(listOption_1.element.type)) {
                return ts.filter(ts.map(value, function (v) { return normalizeOptionValue(listOption_1.element, basePath, v); }), function (v) { return !!v; });
            }
            return value;
        }
        else if (!ts.isString(option.type)) {
            return option.type.get(ts.isString(value) ? value.toLowerCase() : value);
        }
        return normalizeNonListOptionValue(option, basePath, value);
    }
    function normalizeNonListOptionValue(option, basePath, value) {
        if (option.isFilePath) {
            value = ts.normalizePath(ts.combinePaths(basePath, value));
            if (value === "") {
                value = ".";
            }
        }
        return value;
    }
    function convertJsonOptionOfCustomType(opt, value, errors) {
        if (isNullOrUndefined(value))
            return undefined;
        var key = value.toLowerCase();
        var val = opt.type.get(key);
        if (val !== undefined) {
            return val;
        }
        else {
            errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
        }
    }
    function convertJsonOptionOfListType(option, values, basePath, errors) {
        return ts.filter(ts.map(values, function (v) { return convertJsonOption(option.element, v, basePath, errors); }), function (v) { return !!v; });
    }
    function trimString(s) {
        return typeof s.trim === "function" ? s.trim() : s.replace(/^[\s]+|[\s]+$/g, "");
    }
    /**
     * Tests for a path that ends in a recursive directory wildcard.
     * Matches **, \**, **\, and \**\, but not a**b.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*        # matches the recursive directory wildcard "**".
     *  \/?$        # matches an optional trailing directory separator at the end of the string.
     */
    var invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
    /**
     * Tests for a path with multiple recursive directory wildcards.
     * Matches **\** and **\a\**, but not **\a**b.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
     *  \*\*        # matches a recursive directory wildcard "**"
     *  ($|\/)      # matches either the end of the string or a directory separator.
     */
    var invalidMultipleRecursionPatterns = /(^|\/)\*\*\/(.*\/)?\*\*($|\/)/;
    /**
     * Tests for a path where .. appears after a recursive directory wildcard.
     * Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
     *  \.\.        # matches a parent directory path component ".."
     *  ($|\/)      # matches either the end of the string or a directory separator.
     */
    var invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/;
    /**
     * Tests for a path containing a wildcard character in a directory component of the path.
     * Matches \*\, \?\, and \a*b\, but not \a\ or \a\*.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  \/          # matches a directory separator.
     *  [^/]*?      # matches any number of characters excluding directory separators (non-greedy).
     *  [*?]        # matches either a wildcard character (* or ?)
     *  [^/]*       # matches any number of characters excluding directory separators (greedy).
     *  \/          # matches a directory separator.
     */
    var watchRecursivePattern = /\/[^/]*?[*?][^/]*\//;
    /**
     * Matches the portion of a wildcard path that does not contain wildcards.
     * Matches \a of \a\*, or \a\b\c of \a\b\c\?\d.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  ^                   # matches the beginning of the string
     *  [^*?]*              # matches any number of non-wildcard characters
     *  (?=\/[^/]*[*?])     # lookahead that matches a directory separator followed by
     *                      # a path component that contains at least one wildcard character (* or ?).
     */
    var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/;
    /**
     * Expands an array of file specifications.
     *
     * @param filesSpecs The literal file names to include.
     * @param includeSpecs The wildcard file specifications to include.
     * @param excludeSpecs The wildcard file specifications to exclude.
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param errors An array for diagnostic reporting.
     */
    function matchFileNames(filesSpecs, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, jsonSourceFile) {
        basePath = ts.normalizePath(basePath);
        var validatedIncludeSpecs, validatedExcludeSpecs;
        // The exclude spec list is converted into a regular expression, which allows us to quickly
        // test whether a file or directory should be excluded before recursively traversing the
        // file system.
        if (includeSpecs) {
            validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include");
        }
        if (excludeSpecs) {
            validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude");
        }
        // Wildcard directories (provided as part of a wildcard path) are stored in a
        // file map that marks whether it was a regular wildcard match (with a `*` or `?` token),
        // or a recursive directory. This information is used by filesystem watchers to monitor for
        // new entries in these paths.
        var wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
        var spec = { filesSpecs: filesSpecs, includeSpecs: includeSpecs, excludeSpecs: excludeSpecs, validatedIncludeSpecs: validatedIncludeSpecs, validatedExcludeSpecs: validatedExcludeSpecs, wildcardDirectories: wildcardDirectories };
        return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
    }
    /**
     * Gets the file names from the provided config file specs that contain, files, include, exclude and
     * other properties needed to resolve the file names
     * @param spec The config file specs extracted with file names to include, wildcards to include/exclude and other details
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param extraFileExtensions optionaly file extra file extension information from host
     */
    /* @internal */
    function getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions) {
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        basePath = ts.normalizePath(basePath);
        var keyMapper = host.useCaseSensitiveFileNames ? caseSensitiveKeyMapper : caseInsensitiveKeyMapper;
        // Literal file names (provided via the "files" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map later when when including
        // wildcard paths.
        var literalFileMap = ts.createMap();
        // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard, and to handle extension priority.
        var wildcardFileMap = ts.createMap();
        var filesSpecs = spec.filesSpecs, validatedIncludeSpecs = spec.validatedIncludeSpecs, validatedExcludeSpecs = spec.validatedExcludeSpecs, wildcardDirectories = spec.wildcardDirectories;
        // Rather than requery this for each file and filespec, we query the supported extensions
        // once and store it on the expansion context.
        var supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions);
        // Literal files are always included verbatim. An "include" or "exclude" specification cannot
        // remove a literal file.
        if (filesSpecs) {
            for (var _i = 0, filesSpecs_1 = filesSpecs; _i < filesSpecs_1.length; _i++) {
                var fileName = filesSpecs_1[_i];
                var file = ts.getNormalizedAbsolutePath(fileName, basePath);
                literalFileMap.set(keyMapper(file), file);
            }
        }
        if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
            for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined); _a < _b.length; _a++) {
                var file = _b[_a];
                // If we have already included a literal or wildcard path with a
                // higher priority extension, we should skip this file.
                //
                // This handles cases where we may encounter both <file>.ts and
                // <file>.d.ts (or <file>.js if "allowJs" is enabled) in the same
                // directory when they are compilation outputs.
                if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) {
                    continue;
                }
                // We may have included a wildcard path with a lower priority
                // extension due to the user-defined order of entries in the
                // "include" array. If there is a lower priority extension in the
                // same directory, we should remove it.
                removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
                var key = keyMapper(file);
                if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) {
                    wildcardFileMap.set(key, file);
                }
            }
        }
        var literalFiles = ts.arrayFrom(literalFileMap.values());
        var wildcardFiles = ts.arrayFrom(wildcardFileMap.values());
        return {
            fileNames: literalFiles.concat(wildcardFiles),
            wildcardDirectories: wildcardDirectories,
            spec: spec
        };
    }
    ts.getFileNamesFromConfigSpecs = getFileNamesFromConfigSpecs;
    function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) {
        return specs.filter(function (spec) {
            var diag = specToDiagnostic(spec, allowTrailingRecursion);
            if (diag !== undefined) {
                errors.push(createDiagnostic(diag, spec));
            }
            return diag === undefined;
        });
        function createDiagnostic(message, spec) {
            if (jsonSourceFile && jsonSourceFile.jsonObject) {
                for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) {
                    var property = _a[_i];
                    if (ts.isArrayLiteralExpression(property.initializer)) {
                        for (var _b = 0, _c = property.initializer.elements; _b < _c.length; _b++) {
                            var element = _c[_b];
                            if (ts.isStringLiteral(element) && element.text === spec) {
                                return ts.createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec);
                            }
                        }
                    }
                }
            }
            return ts.createCompilerDiagnostic(message, spec);
        }
    }
    function specToDiagnostic(spec, allowTrailingRecursion) {
        if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
        else if (invalidMultipleRecursionPatterns.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0;
        }
        else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
    }
    /**
     * Gets directories in a set of include patterns that should be watched for changes.
     */
    function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) {
        // We watch a directory recursively if it contains a wildcard anywhere in a directory segment
        // of the pattern:
        //
        //  /a/b/**/d   - Watch /a/b recursively to catch changes to any d in any subfolder recursively
        //  /a/b/*/d    - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
        //  /a/b        - Watch /a/b recursively to catch changes to anything in any recursive subfoler
        //
        // We watch a directory without recursion if it contains a wildcard in the file segment of
        // the pattern:
        //
        //  /a/b/*      - Watch /a/b directly to catch any new file
        //  /a/b/a?z    - Watch /a/b directly to catch any new file matching a?z
        var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude");
        var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i");
        var wildcardDirectories = {};
        if (include !== undefined) {
            var recursiveKeys = [];
            for (var _i = 0, include_1 = include; _i < include_1.length; _i++) {
                var file = include_1[_i];
                var spec = ts.normalizePath(ts.combinePaths(path, file));
                if (excludeRegex && excludeRegex.test(spec)) {
                    continue;
                }
                var match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
                if (match) {
                    var key = match.key, flags = match.flags;
                    var existingFlags = wildcardDirectories[key];
                    if (existingFlags === undefined || existingFlags < flags) {
                        wildcardDirectories[key] = flags;
                        if (flags === 1 /* Recursive */) {
                            recursiveKeys.push(key);
                        }
                    }
                }
            }
            // Remove any subpaths under an existing recursively watched directory.
            for (var key in wildcardDirectories) {
                if (ts.hasProperty(wildcardDirectories, key)) {
                    for (var _a = 0, recursiveKeys_1 = recursiveKeys; _a < recursiveKeys_1.length; _a++) {
                        var recursiveKey = recursiveKeys_1[_a];
                        if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
                            delete wildcardDirectories[key];
                        }
                    }
                }
            }
        }
        return wildcardDirectories;
    }
    function getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames) {
        var match = wildcardDirectoryPattern.exec(spec);
        if (match) {
            return {
                key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(),
                flags: watchRecursivePattern.test(spec) ? 1 /* Recursive */ : 0 /* None */
            };
        }
        if (ts.isImplicitGlob(spec)) {
            return { key: spec, flags: 1 /* Recursive */ };
        }
        return undefined;
    }
    /**
     * Determines whether a literal or wildcard file has already been included that has a higher
     * extension priority.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function hasFileWithHigherPriorityExtension(file, literalFiles, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var adjustedExtensionPriority = ts.adjustExtensionPriority(extensionPriority, extensions);
        for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) {
            var higherPriorityExtension = extensions[i];
            var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension));
            if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Removes files included via wildcard expansion with a lower extension priority that have
     * already been included.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function removeWildcardFilesWithLowerPriorityExtension(file, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var nextExtensionPriority = ts.getNextLowestExtensionPriority(extensionPriority, extensions);
        for (var i = nextExtensionPriority; i < extensions.length; i++) {
            var lowerPriorityExtension = extensions[i];
            var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension));
            wildcardFiles.delete(lowerPriorityPath);
        }
    }
    /**
     * Gets a case sensitive key.
     *
     * @param key The original key.
     */
    function caseSensitiveKeyMapper(key) {
        return key;
    }
    /**
     * Gets a case insensitive key.
     *
     * @param key The original key.
     */
    function caseInsensitiveKeyMapper(key) {
        return key.toLowerCase();
    }
    /**
     * Produces a cleaned version of compiler options with personally identifiying info (aka, paths) removed.
     * Also converts enum values back to strings.
     */
    /* @internal */
    function convertCompilerOptionsForTelemetry(opts) {
        var out = {};
        for (var key in opts) {
            if (opts.hasOwnProperty(key)) {
                var type = getOptionFromName(key);
                if (type !== undefined) {
                    out[key] = getOptionValueWithEmptyStrings(opts[key], type);
                }
            }
        }
        return out;
    }
    ts.convertCompilerOptionsForTelemetry = convertCompilerOptionsForTelemetry;
    function getOptionValueWithEmptyStrings(value, option) {
        switch (option.type) {
            case "object":// "paths". Can't get any useful information from the value since we blank out strings, so just return "".
                return "";
            case "string":// Could be any arbitrary string -- use empty string instead.
                return "";
            case "number":// Allow numbers, but be sure to check it's actually a number.
                return typeof value === "number" ? value : "";
            case "boolean":
                return typeof value === "boolean" ? value : "";
            case "list":
                var elementType_1 = option.element;
                return ts.isArray(value) ? value.map(function (v) { return getOptionValueWithEmptyStrings(v, elementType_1); }) : "";
            default:
                return ts.forEachEntry(option.type, function (optionEnumValue, optionStringValue) {
                    if (optionEnumValue === value) {
                        return optionStringValue;
                    }
                });
        }
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    var ScriptSnapshot;
    (function (ScriptSnapshot) {
        var StringScriptSnapshot = /** @class */ (function () {
            function StringScriptSnapshot(text) {
                this.text = text;
            }
            StringScriptSnapshot.prototype.getText = function (start, end) {
                return start === 0 && end === this.text.length
                    ? this.text
                    : this.text.substring(start, end);
            };
            StringScriptSnapshot.prototype.getLength = function () {
                return this.text.length;
            };
            StringScriptSnapshot.prototype.getChangeRange = function () {
                // Text-based snapshots do not support incremental parsing. Return undefined
                // to signal that to the caller.
                return undefined;
            };
            return StringScriptSnapshot;
        }());
        function fromString(text) {
            return new StringScriptSnapshot(text);
        }
        ScriptSnapshot.fromString = fromString;
    })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {}));
    var TextChange = /** @class */ (function () {
        function TextChange() {
        }
        return TextChange;
    }());
    ts.TextChange = TextChange;
    var HighlightSpanKind;
    (function (HighlightSpanKind) {
        HighlightSpanKind["none"] = "none";
        HighlightSpanKind["definition"] = "definition";
        HighlightSpanKind["reference"] = "reference";
        HighlightSpanKind["writtenReference"] = "writtenReference";
    })(HighlightSpanKind = ts.HighlightSpanKind || (ts.HighlightSpanKind = {}));
    var IndentStyle;
    (function (IndentStyle) {
        IndentStyle[IndentStyle["None"] = 0] = "None";
        IndentStyle[IndentStyle["Block"] = 1] = "Block";
        IndentStyle[IndentStyle["Smart"] = 2] = "Smart";
    })(IndentStyle = ts.IndentStyle || (ts.IndentStyle = {}));
    var SymbolDisplayPartKind;
    (function (SymbolDisplayPartKind) {
        SymbolDisplayPartKind[SymbolDisplayPartKind["aliasName"] = 0] = "aliasName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["className"] = 1] = "className";
        SymbolDisplayPartKind[SymbolDisplayPartKind["enumName"] = 2] = "enumName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["fieldName"] = 3] = "fieldName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["interfaceName"] = 4] = "interfaceName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["keyword"] = 5] = "keyword";
        SymbolDisplayPartKind[SymbolDisplayPartKind["lineBreak"] = 6] = "lineBreak";
        SymbolDisplayPartKind[SymbolDisplayPartKind["numericLiteral"] = 7] = "numericLiteral";
        SymbolDisplayPartKind[SymbolDisplayPartKind["stringLiteral"] = 8] = "stringLiteral";
        SymbolDisplayPartKind[SymbolDisplayPartKind["localName"] = 9] = "localName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["methodName"] = 10] = "methodName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["moduleName"] = 11] = "moduleName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["operator"] = 12] = "operator";
        SymbolDisplayPartKind[SymbolDisplayPartKind["parameterName"] = 13] = "parameterName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["propertyName"] = 14] = "propertyName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["punctuation"] = 15] = "punctuation";
        SymbolDisplayPartKind[SymbolDisplayPartKind["space"] = 16] = "space";
        SymbolDisplayPartKind[SymbolDisplayPartKind["text"] = 17] = "text";
        SymbolDisplayPartKind[SymbolDisplayPartKind["typeParameterName"] = 18] = "typeParameterName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["enumMemberName"] = 19] = "enumMemberName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["functionName"] = 20] = "functionName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["regularExpressionLiteral"] = 21] = "regularExpressionLiteral";
    })(SymbolDisplayPartKind = ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {}));
    var OutputFileType;
    (function (OutputFileType) {
        OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
        OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
        OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
    })(OutputFileType = ts.OutputFileType || (ts.OutputFileType = {}));
    var EndOfLineState;
    (function (EndOfLineState) {
        EndOfLineState[EndOfLineState["None"] = 0] = "None";
        EndOfLineState[EndOfLineState["InMultiLineCommentTrivia"] = 1] = "InMultiLineCommentTrivia";
        EndOfLineState[EndOfLineState["InSingleQuoteStringLiteral"] = 2] = "InSingleQuoteStringLiteral";
        EndOfLineState[EndOfLineState["InDoubleQuoteStringLiteral"] = 3] = "InDoubleQuoteStringLiteral";
        EndOfLineState[EndOfLineState["InTemplateHeadOrNoSubstitutionTemplate"] = 4] = "InTemplateHeadOrNoSubstitutionTemplate";
        EndOfLineState[EndOfLineState["InTemplateMiddleOrTail"] = 5] = "InTemplateMiddleOrTail";
        EndOfLineState[EndOfLineState["InTemplateSubstitutionPosition"] = 6] = "InTemplateSubstitutionPosition";
    })(EndOfLineState = ts.EndOfLineState || (ts.EndOfLineState = {}));
    var TokenClass;
    (function (TokenClass) {
        TokenClass[TokenClass["Punctuation"] = 0] = "Punctuation";
        TokenClass[TokenClass["Keyword"] = 1] = "Keyword";
        TokenClass[TokenClass["Operator"] = 2] = "Operator";
        TokenClass[TokenClass["Comment"] = 3] = "Comment";
        TokenClass[TokenClass["Whitespace"] = 4] = "Whitespace";
        TokenClass[TokenClass["Identifier"] = 5] = "Identifier";
        TokenClass[TokenClass["NumberLiteral"] = 6] = "NumberLiteral";
        TokenClass[TokenClass["StringLiteral"] = 7] = "StringLiteral";
        TokenClass[TokenClass["RegExpLiteral"] = 8] = "RegExpLiteral";
    })(TokenClass = ts.TokenClass || (ts.TokenClass = {}));
    var ScriptElementKind;
    (function (ScriptElementKind) {
        ScriptElementKind["unknown"] = "";
        ScriptElementKind["warning"] = "warning";
        /** predefined type (void) or keyword (class) */
        ScriptElementKind["keyword"] = "keyword";
        /** top level script node */
        ScriptElementKind["scriptElement"] = "script";
        /** module foo {} */
        ScriptElementKind["moduleElement"] = "module";
        /** class X {} */
        ScriptElementKind["classElement"] = "class";
        /** var x = class X {} */
        ScriptElementKind["localClassElement"] = "local class";
        /** interface Y {} */
        ScriptElementKind["interfaceElement"] = "interface";
        /** type T = ... */
        ScriptElementKind["typeElement"] = "type";
        /** enum E */
        ScriptElementKind["enumElement"] = "enum";
        ScriptElementKind["enumMemberElement"] = "enum member";
        /**
         * Inside module and script only
         * const v = ..
         */
        ScriptElementKind["variableElement"] = "var";
        /** Inside function */
        ScriptElementKind["localVariableElement"] = "local var";
        /**
         * Inside module and script only
         * function f() { }
         */
        ScriptElementKind["functionElement"] = "function";
        /** Inside function */
        ScriptElementKind["localFunctionElement"] = "local function";
        /** class X { [public|private]* foo() {} } */
        ScriptElementKind["memberFunctionElement"] = "method";
        /** class X { [public|private]* [get|set] foo:number; } */
        ScriptElementKind["memberGetAccessorElement"] = "getter";
        ScriptElementKind["memberSetAccessorElement"] = "setter";
        /**
         * class X { [public|private]* foo:number; }
         * interface Y { foo:number; }
         */
        ScriptElementKind["memberVariableElement"] = "property";
        /** class X { constructor() { } } */
        ScriptElementKind["constructorImplementationElement"] = "constructor";
        /** interface Y { ():number; } */
        ScriptElementKind["callSignatureElement"] = "call";
        /** interface Y { []:number; } */
        ScriptElementKind["indexSignatureElement"] = "index";
        /** interface Y { new():Y; } */
        ScriptElementKind["constructSignatureElement"] = "construct";
        /** function foo(*Y*: string) */
        ScriptElementKind["parameterElement"] = "parameter";
        ScriptElementKind["typeParameterElement"] = "type parameter";
        ScriptElementKind["primitiveType"] = "primitive type";
        ScriptElementKind["label"] = "label";
        ScriptElementKind["alias"] = "alias";
        ScriptElementKind["constElement"] = "const";
        ScriptElementKind["letElement"] = "let";
        ScriptElementKind["directory"] = "directory";
        ScriptElementKind["externalModuleName"] = "external module name";
        /**
         * <JsxTagName attribute1 attribute2={0} />
         */
        ScriptElementKind["jsxAttribute"] = "JSX attribute";
    })(ScriptElementKind = ts.ScriptElementKind || (ts.ScriptElementKind = {}));
    var ScriptElementKindModifier;
    (function (ScriptElementKindModifier) {
        ScriptElementKindModifier["none"] = "";
        ScriptElementKindModifier["publicMemberModifier"] = "public";
        ScriptElementKindModifier["privateMemberModifier"] = "private";
        ScriptElementKindModifier["protectedMemberModifier"] = "protected";
        ScriptElementKindModifier["exportedModifier"] = "export";
        ScriptElementKindModifier["ambientModifier"] = "declare";
        ScriptElementKindModifier["staticModifier"] = "static";
        ScriptElementKindModifier["abstractModifier"] = "abstract";
    })(ScriptElementKindModifier = ts.ScriptElementKindModifier || (ts.ScriptElementKindModifier = {}));
    var ClassificationTypeNames;
    (function (ClassificationTypeNames) {
        ClassificationTypeNames["comment"] = "comment";
        ClassificationTypeNames["identifier"] = "identifier";
        ClassificationTypeNames["keyword"] = "keyword";
        ClassificationTypeNames["numericLiteral"] = "number";
        ClassificationTypeNames["operator"] = "operator";
        ClassificationTypeNames["stringLiteral"] = "string";
        ClassificationTypeNames["whiteSpace"] = "whitespace";
        ClassificationTypeNames["text"] = "text";
        ClassificationTypeNames["punctuation"] = "punctuation";
        ClassificationTypeNames["className"] = "class name";
        ClassificationTypeNames["enumName"] = "enum name";
        ClassificationTypeNames["interfaceName"] = "interface name";
        ClassificationTypeNames["moduleName"] = "module name";
        ClassificationTypeNames["typeParameterName"] = "type parameter name";
        ClassificationTypeNames["typeAliasName"] = "type alias name";
        ClassificationTypeNames["parameterName"] = "parameter name";
        ClassificationTypeNames["docCommentTagName"] = "doc comment tag name";
        ClassificationTypeNames["jsxOpenTagName"] = "jsx open tag name";
        ClassificationTypeNames["jsxCloseTagName"] = "jsx close tag name";
        ClassificationTypeNames["jsxSelfClosingTagName"] = "jsx self closing tag name";
        ClassificationTypeNames["jsxAttribute"] = "jsx attribute";
        ClassificationTypeNames["jsxText"] = "jsx text";
        ClassificationTypeNames["jsxAttributeStringLiteralValue"] = "jsx attribute string literal value";
    })(ClassificationTypeNames = ts.ClassificationTypeNames || (ts.ClassificationTypeNames = {}));
    var ClassificationType;
    (function (ClassificationType) {
        ClassificationType[ClassificationType["comment"] = 1] = "comment";
        ClassificationType[ClassificationType["identifier"] = 2] = "identifier";
        ClassificationType[ClassificationType["keyword"] = 3] = "keyword";
        ClassificationType[ClassificationType["numericLiteral"] = 4] = "numericLiteral";
        ClassificationType[ClassificationType["operator"] = 5] = "operator";
        ClassificationType[ClassificationType["stringLiteral"] = 6] = "stringLiteral";
        ClassificationType[ClassificationType["regularExpressionLiteral"] = 7] = "regularExpressionLiteral";
        ClassificationType[ClassificationType["whiteSpace"] = 8] = "whiteSpace";
        ClassificationType[ClassificationType["text"] = 9] = "text";
        ClassificationType[ClassificationType["punctuation"] = 10] = "punctuation";
        ClassificationType[ClassificationType["className"] = 11] = "className";
        ClassificationType[ClassificationType["enumName"] = 12] = "enumName";
        ClassificationType[ClassificationType["interfaceName"] = 13] = "interfaceName";
        ClassificationType[ClassificationType["moduleName"] = 14] = "moduleName";
        ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName";
        ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName";
        ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName";
        ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName";
        ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName";
        ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName";
        ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName";
        ClassificationType[ClassificationType["jsxAttribute"] = 22] = "jsxAttribute";
        ClassificationType[ClassificationType["jsxText"] = 23] = "jsxText";
        ClassificationType[ClassificationType["jsxAttributeStringLiteralValue"] = 24] = "jsxAttributeStringLiteralValue";
    })(ClassificationType = ts.ClassificationType || (ts.ClassificationType = {}));
})(ts || (ts = {}));
// These utilities are common to multiple language service features.
/* @internal */
var ts;
(function (ts) {
    ts.scanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ true);
    var SemanticMeaning;
    (function (SemanticMeaning) {
        SemanticMeaning[SemanticMeaning["None"] = 0] = "None";
        SemanticMeaning[SemanticMeaning["Value"] = 1] = "Value";
        SemanticMeaning[SemanticMeaning["Type"] = 2] = "Type";
        SemanticMeaning[SemanticMeaning["Namespace"] = 4] = "Namespace";
        SemanticMeaning[SemanticMeaning["All"] = 7] = "All";
    })(SemanticMeaning = ts.SemanticMeaning || (ts.SemanticMeaning = {}));
    function getMeaningFromDeclaration(node) {
        switch (node.kind) {
            case 146 /* Parameter */:
            case 226 /* VariableDeclaration */:
            case 176 /* BindingElement */:
            case 149 /* PropertyDeclaration */:
            case 148 /* PropertySignature */:
            case 261 /* PropertyAssignment */:
            case 262 /* ShorthandPropertyAssignment */:
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
            case 152 /* Constructor */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
            case 187 /* ArrowFunction */:
            case 260 /* CatchClause */:
            case 253 /* JsxAttribute */:
                return 1 /* Value */;
            case 145 /* TypeParameter */:
            case 230 /* InterfaceDeclaration */:
            case 231 /* TypeAliasDeclaration */:
            case 163 /* TypeLiteral */:
                return 2 /* Type */;
            case 283 /* JSDocTypedefTag */:
                // If it has no name node, it shares the name with the value declaration below it.
                return node.name === undefined ? 1 /* Value */ | 2 /* Type */ : 2 /* Type */;
            case 264 /* EnumMember */:
            case 229 /* ClassDeclaration */:
                return 1 /* Value */ | 2 /* Type */;
            case 233 /* ModuleDeclaration */:
                if (ts.isAmbientModule(node)) {
                    return 4 /* Namespace */ | 1 /* Value */;
                }
                else if (ts.getModuleInstanceState(node) === 1 /* Instantiated */) {
                    return 4 /* Namespace */ | 1 /* Value */;
                }
                else {
                    return 4 /* Namespace */;
                }
            case 232 /* EnumDeclaration */:
            case 241 /* NamedImports */:
            case 242 /* ImportSpecifier */:
            case 237 /* ImportEqualsDeclaration */:
            case 238 /* ImportDeclaration */:
            case 243 /* ExportAssignment */:
            case 244 /* ExportDeclaration */:
                return 7 /* All */;
            // An external module can be a Value
            case 265 /* SourceFile */:
                return 4 /* Namespace */ | 1 /* Value */;
        }
        return 7 /* All */;
    }
    ts.getMeaningFromDeclaration = getMeaningFromDeclaration;
    function getMeaningFromLocation(node) {
        if (node.kind === 265 /* SourceFile */) {
            return 1 /* Value */;
        }
        else if (node.parent.kind === 243 /* ExportAssignment */) {
            return 7 /* All */;
        }
        else if (isInRightSideOfInternalImportEqualsDeclaration(node)) {
            return getMeaningFromRightHandSideOfImportEquals(node);
        }
        else if (ts.isDeclarationName(node)) {
            return getMeaningFromDeclaration(node.parent);
        }
        else if (isTypeReference(node)) {
            return 2 /* Type */;
        }
        else if (isNamespaceReference(node)) {
            return 4 /* Namespace */;
        }
        else if (ts.isTypeParameterDeclaration(node.parent)) {
            ts.Debug.assert(ts.isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName
            return 2 /* Type */;
        }
        else {
            return 1 /* Value */;
        }
    }
    ts.getMeaningFromLocation = getMeaningFromLocation;
    function getMeaningFromRightHandSideOfImportEquals(node) {
        ts.Debug.assert(node.kind === 71 /* Identifier */);
        //     import a = |b|; // Namespace
        //     import a = |b.c|; // Value, type, namespace
        //     import a = |b.c|.d; // Namespace
        if (node.parent.kind === 143 /* QualifiedName */ &&
            node.parent.right === node &&
            node.parent.parent.kind === 237 /* ImportEqualsDeclaration */) {
            return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
        }
        return 4 /* Namespace */;
    }
    function isInRightSideOfInternalImportEqualsDeclaration(node) {
        while (node.parent.kind === 143 /* QualifiedName */) {
            node = node.parent;
        }
        return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node;
    }
    ts.isInRightSideOfInternalImportEqualsDeclaration = isInRightSideOfInternalImportEqualsDeclaration;
    function isNamespaceReference(node) {
        return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node);
    }
    function isQualifiedNameNamespaceReference(node) {
        var root = node;
        var isLastClause = true;
        if (root.parent.kind === 143 /* QualifiedName */) {
            while (root.parent && root.parent.kind === 143 /* QualifiedName */) {
                root = root.parent;
            }
            isLastClause = root.right === node;
        }
        return root.parent.kind === 159 /* TypeReference */ && !isLastClause;
    }
    function isPropertyAccessNamespaceReference(node) {
        var root = node;
        var isLastClause = true;
        if (root.parent.kind === 179 /* PropertyAccessExpression */) {
            while (root.parent && root.parent.kind === 179 /* PropertyAccessExpression */) {
                root = root.parent;
            }
            isLastClause = root.name === node;
        }
        if (!isLastClause && root.parent.kind === 201 /* ExpressionWithTypeArguments */ && root.parent.parent.kind === 259 /* HeritageClause */) {
            var decl = root.parent.parent.parent;
            return (decl.kind === 229 /* ClassDeclaration */ && root.parent.parent.token === 108 /* ImplementsKeyword */) ||
                (decl.kind === 230 /* InterfaceDeclaration */ && root.parent.parent.token === 85 /* ExtendsKeyword */);
        }
        return false;
    }
    function isTypeReference(node) {
        if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
            node = node.parent;
        }
        switch (node.kind) {
            case 99 /* ThisKeyword */:
                return !ts.isPartOfExpression(node);
            case 169 /* ThisType */:
                return true;
        }
        switch (node.parent.kind) {
            case 159 /* TypeReference */:
                return true;
            case 201 /* ExpressionWithTypeArguments */:
                return !ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent);
        }
        return false;
    }
    function isCallExpressionTarget(node) {
        return isCallOrNewExpressionTarget(node, 181 /* CallExpression */);
    }
    ts.isCallExpressionTarget = isCallExpressionTarget;
    function isNewExpressionTarget(node) {
        return isCallOrNewExpressionTarget(node, 182 /* NewExpression */);
    }
    ts.isNewExpressionTarget = isNewExpressionTarget;
    function isCallOrNewExpressionTarget(node, kind) {
        var target = climbPastPropertyAccess(node);
        return target && target.parent && target.parent.kind === kind && target.parent.expression === target;
    }
    function climbPastPropertyAccess(node) {
        return isRightSideOfPropertyAccess(node) ? node.parent : node;
    }
    ts.climbPastPropertyAccess = climbPastPropertyAccess;
    function getTargetLabel(referenceNode, labelName) {
        while (referenceNode) {
            if (referenceNode.kind === 222 /* LabeledStatement */ && referenceNode.label.escapedText === labelName) {
                return referenceNode.label;
            }
            referenceNode = referenceNode.parent;
        }
        return undefined;
    }
    ts.getTargetLabel = getTargetLabel;
    function isJumpStatementTarget(node) {
        return node.kind === 71 /* Identifier */ &&
            (node.parent.kind === 218 /* BreakStatement */ || node.parent.kind === 217 /* ContinueStatement */) &&
            node.parent.label === node;
    }
    ts.isJumpStatementTarget = isJumpStatementTarget;
    function isLabelOfLabeledStatement(node) {
        return node.kind === 71 /* Identifier */ &&
            node.parent.kind === 222 /* LabeledStatement */ &&
            node.parent.label === node;
    }
    function isLabelName(node) {
        return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
    }
    ts.isLabelName = isLabelName;
    function isRightSideOfQualifiedName(node) {
        return node.parent.kind === 143 /* QualifiedName */ && node.parent.right === node;
    }
    ts.isRightSideOfQualifiedName = isRightSideOfQualifiedName;
    function isRightSideOfPropertyAccess(node) {
        return node && node.parent && node.parent.kind === 179 /* PropertyAccessExpression */ && node.parent.name === node;
    }
    ts.isRightSideOfPropertyAccess = isRightSideOfPropertyAccess;
    function isNameOfModuleDeclaration(node) {
        return node.parent.kind === 233 /* ModuleDeclaration */ && node.parent.name === node;
    }
    ts.isNameOfModuleDeclaration = isNameOfModuleDeclaration;
    function isNameOfFunctionDeclaration(node) {
        return node.kind === 71 /* Identifier */ &&
            ts.isFunctionLike(node.parent) && node.parent.name === node;
    }
    ts.isNameOfFunctionDeclaration = isNameOfFunctionDeclaration;
    function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) {
        switch (node.parent.kind) {
            case 149 /* PropertyDeclaration */:
            case 148 /* PropertySignature */:
            case 261 /* PropertyAssignment */:
            case 264 /* EnumMember */:
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 233 /* ModuleDeclaration */:
                return ts.getNameOfDeclaration(node.parent) === node;
            case 180 /* ElementAccessExpression */:
                return node.parent.argumentExpression === node;
            case 144 /* ComputedPropertyName */:
                return true;
            case 173 /* LiteralType */:
                return node.parent.parent.kind === 171 /* IndexedAccessType */;
        }
    }
    ts.isLiteralNameOfPropertyDeclarationOrIndexAccess = isLiteralNameOfPropertyDeclarationOrIndexAccess;
    function isExpressionOfExternalModuleImportEqualsDeclaration(node) {
        return ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
            ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
    }
    ts.isExpressionOfExternalModuleImportEqualsDeclaration = isExpressionOfExternalModuleImportEqualsDeclaration;
    function getContainerNode(node) {
        if (node.kind === 283 /* JSDocTypedefTag */) {
            // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope.
            // node.parent = the JSDoc comment, node.parent.parent = the node having the comment.
            // Then we get parent again in the loop.
            node = node.parent.parent;
        }
        while (true) {
            node = node.parent;
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 265 /* SourceFile */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 229 /* ClassDeclaration */:
                case 230 /* InterfaceDeclaration */:
                case 232 /* EnumDeclaration */:
                case 233 /* ModuleDeclaration */:
                    return node;
            }
        }
    }
    ts.getContainerNode = getContainerNode;
    function getNodeKind(node) {
        switch (node.kind) {
            case 265 /* SourceFile */:
                return ts.isExternalModule(node) ? "module" /* moduleElement */ : "script" /* scriptElement */;
            case 233 /* ModuleDeclaration */:
                return "module" /* moduleElement */;
            case 229 /* ClassDeclaration */:
            case 199 /* ClassExpression */:
                return "class" /* classElement */;
            case 230 /* InterfaceDeclaration */: return "interface" /* interfaceElement */;
            case 231 /* TypeAliasDeclaration */: return "type" /* typeElement */;
            case 232 /* EnumDeclaration */: return "enum" /* enumElement */;
            case 226 /* VariableDeclaration */:
                return getKindOfVariableDeclaration(node);
            case 176 /* BindingElement */:
                return getKindOfVariableDeclaration(ts.getRootDeclaration(node));
            case 187 /* ArrowFunction */:
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
                return "function" /* functionElement */;
            case 153 /* GetAccessor */: return "getter" /* memberGetAccessorElement */;
            case 154 /* SetAccessor */: return "setter" /* memberSetAccessorElement */;
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
                return "method" /* memberFunctionElement */;
            case 149 /* PropertyDeclaration */:
            case 148 /* PropertySignature */:
                return "property" /* memberVariableElement */;
            case 157 /* IndexSignature */: return "index" /* indexSignatureElement */;
            case 156 /* ConstructSignature */: return "construct" /* constructSignatureElement */;
            case 155 /* CallSignature */: return "call" /* callSignatureElement */;
            case 152 /* Constructor */: return "constructor" /* constructorImplementationElement */;
            case 145 /* TypeParameter */: return "type parameter" /* typeParameterElement */;
            case 264 /* EnumMember */: return "enum member" /* enumMemberElement */;
            case 146 /* Parameter */: return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) ? "property" /* memberVariableElement */ : "parameter" /* parameterElement */;
            case 237 /* ImportEqualsDeclaration */:
            case 242 /* ImportSpecifier */:
            case 239 /* ImportClause */:
            case 246 /* ExportSpecifier */:
            case 240 /* NamespaceImport */:
                return "alias" /* alias */;
            case 283 /* JSDocTypedefTag */:
                return "type" /* typeElement */;
            case 194 /* BinaryExpression */:
                var kind = ts.getSpecialPropertyAssignmentKind(node);
                var right = node.right;
                switch (kind) {
                    case 0 /* None */:
                        return "" /* unknown */;
                    case 1 /* ExportsProperty */:
                    case 2 /* ModuleExports */:
                        var rightKind = getNodeKind(right);
                        return rightKind === "" /* unknown */ ? "const" /* constElement */ : rightKind;
                    case 3 /* PrototypeProperty */:
                        return "method" /* memberFunctionElement */; // instance method
                    case 4 /* ThisProperty */:
                        return "property" /* memberVariableElement */; // property
                    case 5 /* Property */:
                        // static method / property
                        return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
                    default: {
                        ts.assertTypeIsNever(kind);
                        return "" /* unknown */;
                    }
                }
            default:
                return "" /* unknown */;
        }
        function getKindOfVariableDeclaration(v) {
            return ts.isConst(v)
                ? "const" /* constElement */
                : ts.isLet(v)
                    ? "let" /* letElement */
                    : "var" /* variableElement */;
        }
    }
    ts.getNodeKind = getNodeKind;
    function isThis(node) {
        switch (node.kind) {
            case 99 /* ThisKeyword */:
                // case SyntaxKind.ThisType: TODO: GH#9267
                return true;
            case 71 /* Identifier */:
                // 'this' as a parameter
                return ts.identifierIsThisKeyword(node) && node.parent.kind === 146 /* Parameter */;
            default:
                return false;
        }
    }
    ts.isThis = isThis;
    // Matches the beginning of a triple slash directive
    var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
    function getLineStartPositionForPosition(position, sourceFile) {
        var lineStarts = ts.getLineStarts(sourceFile);
        var line = sourceFile.getLineAndCharacterOfPosition(position).line;
        return lineStarts[line];
    }
    ts.getLineStartPositionForPosition = getLineStartPositionForPosition;
    function rangeContainsRange(r1, r2) {
        return startEndContainsRange(r1.pos, r1.end, r2);
    }
    ts.rangeContainsRange = rangeContainsRange;
    function startEndContainsRange(start, end, range) {
        return start <= range.pos && end >= range.end;
    }
    ts.startEndContainsRange = startEndContainsRange;
    function rangeContainsStartEnd(range, start, end) {
        return range.pos <= start && range.end >= end;
    }
    ts.rangeContainsStartEnd = rangeContainsStartEnd;
    function rangeOverlapsWithStartEnd(r1, start, end) {
        return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end);
    }
    ts.rangeOverlapsWithStartEnd = rangeOverlapsWithStartEnd;
    function startEndOverlapsWithStartEnd(start1, end1, start2, end2) {
        var start = Math.max(start1, start2);
        var end = Math.min(end1, end2);
        return start < end;
    }
    ts.startEndOverlapsWithStartEnd = startEndOverlapsWithStartEnd;
    /**
     * Assumes `candidate.start <= position` holds.
     */
    function positionBelongsToNode(candidate, position, sourceFile) {
        return position < candidate.end || !isCompletedNode(candidate, sourceFile);
    }
    ts.positionBelongsToNode = positionBelongsToNode;
    function isCompletedNode(n, sourceFile) {
        if (ts.nodeIsMissing(n)) {
            return false;
        }
        switch (n.kind) {
            case 229 /* ClassDeclaration */:
            case 230 /* InterfaceDeclaration */:
            case 232 /* EnumDeclaration */:
            case 178 /* ObjectLiteralExpression */:
            case 174 /* ObjectBindingPattern */:
            case 163 /* TypeLiteral */:
            case 207 /* Block */:
            case 234 /* ModuleBlock */:
            case 235 /* CaseBlock */:
            case 241 /* NamedImports */:
            case 245 /* NamedExports */:
                return nodeEndsWith(n, 18 /* CloseBraceToken */, sourceFile);
            case 260 /* CatchClause */:
                return isCompletedNode(n.block, sourceFile);
            case 182 /* NewExpression */:
                if (!n.arguments) {
                    return true;
                }
            // falls through
            case 181 /* CallExpression */:
            case 185 /* ParenthesizedExpression */:
            case 168 /* ParenthesizedType */:
                return nodeEndsWith(n, 20 /* CloseParenToken */, sourceFile);
            case 160 /* FunctionType */:
            case 161 /* ConstructorType */:
                return isCompletedNode(n.type, sourceFile);
            case 152 /* Constructor */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
            case 228 /* FunctionDeclaration */:
            case 186 /* FunctionExpression */:
            case 151 /* MethodDeclaration */:
            case 150 /* MethodSignature */:
            case 156 /* ConstructSignature */:
            case 155 /* CallSignature */:
            case 187 /* ArrowFunction */:
                if (n.body) {
                    return isCompletedNode(n.body, sourceFile);
                }
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                // Even though type parameters can be unclosed, we can get away with
                // having at least a closing paren.
                return hasChildOfKind(n, 20 /* CloseParenToken */, sourceFile);
            case 233 /* ModuleDeclaration */:
                return n.body && isCompletedNode(n.body, sourceFile);
            case 211 /* IfStatement */:
                if (n.elseStatement) {
                    return isCompletedNode(n.elseStatement, sourceFile);
                }
                return isCompletedNode(n.thenStatement, sourceFile);
            case 210 /* ExpressionStatement */:
                return isCompletedNode(n.expression, sourceFile) ||
                    hasChildOfKind(n, 25 /* SemicolonToken */);
            case 177 /* ArrayLiteralExpression */:
            case 175 /* ArrayBindingPattern */:
            case 180 /* ElementAccessExpression */:
            case 144 /* ComputedPropertyName */:
            case 165 /* TupleType */:
                return nodeEndsWith(n, 22 /* CloseBracketToken */, sourceFile);
            case 157 /* IndexSignature */:
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                return hasChildOfKind(n, 22 /* CloseBracketToken */, sourceFile);
            case 257 /* CaseClause */:
            case 258 /* DefaultClause */:
                // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed
                return false;
            case 214 /* ForStatement */:
            case 215 /* ForInStatement */:
            case 216 /* ForOfStatement */:
            case 213 /* WhileStatement */:
                return isCompletedNode(n.statement, sourceFile);
            case 212 /* DoStatement */:
                // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
                var hasWhileKeyword = findChildOfKind(n, 106 /* WhileKeyword */, sourceFile);
                if (hasWhileKeyword) {
                    return nodeEndsWith(n, 20 /* CloseParenToken */, sourceFile);
                }
                return isCompletedNode(n.statement, sourceFile);
            case 162 /* TypeQuery */:
                return isCompletedNode(n.exprName, sourceFile);
            case 189 /* TypeOfExpression */:
            case 188 /* DeleteExpression */:
            case 190 /* VoidExpression */:
            case 197 /* YieldExpression */:
            case 198 /* SpreadElement */:
                var unaryWordExpression = n;
                return isCompletedNode(unaryWordExpression.expression, sourceFile);
            case 183 /* TaggedTemplateExpression */:
                return isCompletedNode(n.template, sourceFile);
            case 196 /* TemplateExpression */:
                var lastSpan = ts.lastOrUndefined(n.templateSpans);
                return isCompletedNode(lastSpan, sourceFile);
            case 205 /* TemplateSpan */:
                return ts.nodeIsPresent(n.literal);
            case 244 /* ExportDeclaration */:
            case 238 /* ImportDeclaration */:
                return ts.nodeIsPresent(n.moduleSpecifier);
            case 192 /* PrefixUnaryExpression */:
                return isCompletedNode(n.operand, sourceFile);
            case 194 /* BinaryExpression */:
                return isCompletedNode(n.right, sourceFile);
            case 195 /* ConditionalExpression */:
                return isCompletedNode(n.whenFalse, sourceFile);
            default:
                return true;
        }
    }
    ts.isCompletedNode = isCompletedNode;
    /*
     * Checks if node ends with 'expectedLastToken'.
     * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'.
     */
    function nodeEndsWith(n, expectedLastToken, sourceFile) {
        var children = n.getChildren(sourceFile);
        if (children.length) {
            var last_2 = ts.lastOrUndefined(children);
            if (last_2.kind === expectedLastToken) {
                return true;
            }
            else if (last_2.kind === 25 /* SemicolonToken */ && children.length !== 1) {
                return children[children.length - 2].kind === expectedLastToken;
            }
        }
        return false;
    }
    function findListItemInfo(node) {
        var list = findContainingList(node);
        // It is possible at this point for syntaxList to be undefined, either if
        // node.parent had no list child, or if none of its list children contained
        // the span of node. If this happens, return undefined. The caller should
        // handle this case.
        if (!list) {
            return undefined;
        }
        var children = list.getChildren();
        var listItemIndex = ts.indexOfNode(children, node);
        return {
            listItemIndex: listItemIndex,
            list: list
        };
    }
    ts.findListItemInfo = findListItemInfo;
    function hasChildOfKind(n, kind, sourceFile) {
        return !!findChildOfKind(n, kind, sourceFile);
    }
    ts.hasChildOfKind = hasChildOfKind;
    function findChildOfKind(n, kind, sourceFile) {
        return ts.forEach(n.getChildren(sourceFile), function (c) { return c.kind === kind && c; });
    }
    ts.findChildOfKind = findChildOfKind;
    function findContainingList(node) {
        // The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
        // be parented by the container of the SyntaxList, not the SyntaxList itself.
        // In order to find the list item index, we first need to locate SyntaxList itself and then search
        // for the position of the relevant node (or comma).
        var syntaxList = ts.forEach(node.parent.getChildren(), function (c) {
            // find syntax list that covers the span of the node
            if (ts.isSyntaxList(c) && c.pos <= node.pos && c.end >= node.end) {
                return c;
            }
        });
        // Either we didn't find an appropriate list, or the list must contain us.
        ts.Debug.assert(!syntaxList || ts.contains(syntaxList.getChildren(), node));
        return syntaxList;
    }
    ts.findContainingList = findContainingList;
    /* Gets the token whose text has range [start, end) and
     * position >= start and (position < end or (position === end && token is keyword or identifier))
     */
    function getTouchingWord(sourceFile, position, includeJsDocComment) {
        return getTouchingToken(sourceFile, position, includeJsDocComment, function (n) { return isWord(n.kind); });
    }
    ts.getTouchingWord = getTouchingWord;
    /* Gets the token whose text has range [start, end) and position >= start
     * and (position < end or (position === end && token is keyword or identifier or numeric/string literal))
     */
    function getTouchingPropertyName(sourceFile, position, includeJsDocComment) {
        return getTouchingToken(sourceFile, position, includeJsDocComment, function (n) { return isPropertyName(n.kind); });
    }
    ts.getTouchingPropertyName = getTouchingPropertyName;
    /**
     * Returns the token if position is in [start, end).
     * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true
     */
    function getTouchingToken(sourceFile, position, includeJsDocComment, includePrecedingTokenAtEndPosition) {
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false, includeJsDocComment);
    }
    ts.getTouchingToken = getTouchingToken;
    /** Returns a token if position is in [start-of-leading-trivia, end) */
    function getTokenAtPosition(sourceFile, position, includeJsDocComment, includeEndPosition) {
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, includeEndPosition, includeJsDocComment);
    }
    ts.getTokenAtPosition = getTokenAtPosition;
    /** Get the token whose text contains the position */
    function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition, includeJsDocComment) {
        var current = sourceFile;
        outer: while (true) {
            if (ts.isToken(current)) {
                // exit early
                return current;
            }
            // find the child that contains 'position'
            for (var _i = 0, _a = current.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                if (!includeJsDocComment && ts.isJSDocNode(child)) {
                    continue;
                }
                var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment);
                if (start > position) {
                    // If this child begins after position, then all subsequent children will as well.
                    break;
                }
                var end = child.getEnd();
                if (position < end || (position === end && (child.kind === 1 /* EndOfFileToken */ || includeEndPosition))) {
                    current = child;
                    continue outer;
                }
                else if (includePrecedingTokenAtEndPosition && end === position) {
                    var previousToken = findPrecedingToken(position, sourceFile, child);
                    if (previousToken && includePrecedingTokenAtEndPosition(previousToken)) {
                        return previousToken;
                    }
                }
            }
            return current;
        }
    }
    /**
     * The token on the left of the position is the token that strictly includes the position
     * or sits to the left of the cursor if it is on a boundary. For example
     *
     *   fo|o               -> will return foo
     *   foo <comment> |bar -> will return foo
     *
     */
    function findTokenOnLeftOfPosition(file, position) {
        // Ideally, getTokenAtPosition should return a token. However, it is currently
        // broken, so we do a check to make sure the result was indeed a token.
        var tokenAtPosition = getTokenAtPosition(file, position, /*includeJsDocComment*/ false);
        if (ts.isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
            return tokenAtPosition;
        }
        return findPrecedingToken(position, file);
    }
    ts.findTokenOnLeftOfPosition = findTokenOnLeftOfPosition;
    function findNextToken(previousToken, parent) {
        return find(parent);
        function find(n) {
            if (ts.isToken(n) && n.pos === previousToken.end) {
                // this is token that starts at the end of previous token - return it
                return n;
            }
            var children = n.getChildren();
            for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
                var child = children_2[_i];
                var shouldDiveInChildNode = 
                // previous token is enclosed somewhere in the child
                (child.pos <= previousToken.pos && child.end > previousToken.end) ||
                    // previous token ends exactly at the beginning of child
                    (child.pos === previousToken.end);
                if (shouldDiveInChildNode && nodeHasTokens(child)) {
                    return find(child);
                }
            }
            return undefined;
        }
    }
    ts.findNextToken = findNextToken;
    /**
     * Finds the rightmost token satisfying `token.end <= position`,
     * excluding `JsxText` tokens containing only whitespace.
     */
    function findPrecedingToken(position, sourceFile, startNode, includeJsDoc) {
        var result = find(startNode || sourceFile);
        ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result)));
        return result;
        function findRightmostToken(n) {
            if (ts.isToken(n)) {
                return n;
            }
            var children = n.getChildren();
            var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length);
            return candidate && findRightmostToken(candidate);
        }
        function find(n) {
            if (ts.isToken(n)) {
                return n;
            }
            var children = n.getChildren();
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                // Note that the span of a node's tokens is [node.getStart(...), node.end).
                // Given that `position < child.end` and child has constituent tokens, we distinguish these cases:
                // 1) `position` precedes `child`'s tokens or `child` has no tokens (ie: in a comment or whitespace preceding `child`):
                // we need to find the last token in a previous child.
                // 2) `position` is within the same span: we recurse on `child`.
                if (position < child.end) {
                    var start = child.getStart(sourceFile, includeJsDoc);
                    var lookInPreviousChild = (start >= position) || // cursor in the leading trivia
                        !nodeHasTokens(child) ||
                        isWhiteSpaceOnlyJsxText(child);
                    if (lookInPreviousChild) {
                        // actual start of the node is past the position - previous token should be at the end of previous child
                        var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i);
                        return candidate && findRightmostToken(candidate);
                    }
                    else {
                        // candidate should be in this node
                        return find(child);
                    }
                }
            }
            ts.Debug.assert(startNode !== undefined || n.kind === 265 /* SourceFile */ || ts.isJSDocCommentContainingNode(n));
            // Here we know that none of child token nodes embrace the position,
            // the only known case is when position is at the end of the file.
            // Try to find the rightmost token in the file without filtering.
            // Namely we are skipping the check: 'position < node.end'
            if (children.length) {
                var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length);
                return candidate && findRightmostToken(candidate);
            }
        }
        /**
         * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens.
         */
        function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) {
            for (var i = exclusiveStartPosition - 1; i >= 0; i--) {
                var child = children[i];
                if (isWhiteSpaceOnlyJsxText(child)) {
                    ts.Debug.assert(i > 0, "`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`");
                }
                else if (nodeHasTokens(children[i])) {
                    return children[i];
                }
            }
        }
    }
    ts.findPrecedingToken = findPrecedingToken;
    function isInString(sourceFile, position) {
        var previousToken = findPrecedingToken(position, sourceFile);
        if (previousToken && ts.isStringTextContainingNode(previousToken)) {
            var start = previousToken.getStart();
            var end = previousToken.getEnd();
            // To be "in" one of these literals, the position has to be:
            //   1. entirely within the token text.
            //   2. at the end position of an unterminated token.
            //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
            if (start < position && position < end) {
                return true;
            }
            if (position === end) {
                return !!previousToken.isUnterminated;
            }
        }
        return false;
    }
    ts.isInString = isInString;
    /**
     * returns true if the position is in between the open and close elements of an JSX expression.
     */
    function isInsideJsxElementOrAttribute(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
        if (!token) {
            return false;
        }
        if (token.kind === 10 /* JsxText */) {
            return true;
        }
        // <div>Hello |</div>
        if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 10 /* JsxText */) {
            return true;
        }
        // <div> { | </div> or <div a={| </div>
        if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 256 /* JsxExpression */) {
            return true;
        }
        // <div> {
        // |
        // } < /div>
        if (token && token.kind === 18 /* CloseBraceToken */ && token.parent.kind === 256 /* JsxExpression */) {
            return true;
        }
        // <div>|</div>
        if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 252 /* JsxClosingElement */) {
            return true;
        }
        return false;
    }
    ts.isInsideJsxElementOrAttribute = isInsideJsxElementOrAttribute;
    function isWhiteSpaceOnlyJsxText(node) {
        return ts.isJsxText(node) && node.containsOnlyWhiteSpaces;
    }
    ts.isWhiteSpaceOnlyJsxText = isWhiteSpaceOnlyJsxText;
    function isInTemplateString(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
        return ts.isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile);
    }
    ts.isInTemplateString = isInTemplateString;
    /**
     * Returns true if the cursor at position in sourceFile is within a comment.
     *
     * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
     * @param predicate Additional predicate to test on the comment range.
     */
    function isInComment(sourceFile, position, tokenAtPosition, predicate) {
        return !!ts.formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ false, /*precedingToken*/ undefined, tokenAtPosition, predicate);
    }
    ts.isInComment = isInComment;
    function hasDocComment(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
        // First, we have to see if this position actually landed in a comment.
        var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
        return ts.forEach(commentRanges, jsDocPrefix);
        function jsDocPrefix(c) {
            var text = sourceFile.text;
            return text.length >= c.pos + 3 && text[c.pos] === "/" && text[c.pos + 1] === "*" && text[c.pos + 2] === "*";
        }
    }
    ts.hasDocComment = hasDocComment;
    function nodeHasTokens(n) {
        // If we have a token or node that has a non-zero width, it must have tokens.
        // Note: getWidth() does not take trivia into account.
        return n.getWidth() !== 0;
    }
    function getNodeModifiers(node) {
        var flags = ts.getCombinedModifierFlags(node);
        var result = [];
        if (flags & 8 /* Private */)
            result.push("private" /* privateMemberModifier */);
        if (flags & 16 /* Protected */)
            result.push("protected" /* protectedMemberModifier */);
        if (flags & 4 /* Public */)
            result.push("public" /* publicMemberModifier */);
        if (flags & 32 /* Static */)
            result.push("static" /* staticModifier */);
        if (flags & 128 /* Abstract */)
            result.push("abstract" /* abstractModifier */);
        if (flags & 1 /* Export */)
            result.push("export" /* exportedModifier */);
        if (ts.isInAmbientContext(node))
            result.push("declare" /* ambientModifier */);
        return result.length > 0 ? result.join(",") : "" /* none */;
    }
    ts.getNodeModifiers = getNodeModifiers;
    function getTypeArgumentOrTypeParameterList(node) {
        if (node.kind === 159 /* TypeReference */ || node.kind === 181 /* CallExpression */) {
            return node.typeArguments;
        }
        if (ts.isFunctionLike(node) || node.kind === 229 /* ClassDeclaration */ || node.kind === 230 /* InterfaceDeclaration */) {
            return node.typeParameters;
        }
        return undefined;
    }
    ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList;
    function isWord(kind) {
        return kind === 71 /* Identifier */ || ts.isKeyword(kind);
    }
    ts.isWord = isWord;
    function isPropertyName(kind) {
        return kind === 9 /* StringLiteral */ || kind === 8 /* NumericLiteral */ || isWord(kind);
    }
    function isComment(kind) {
        return kind === 2 /* SingleLineCommentTrivia */ || kind === 3 /* MultiLineCommentTrivia */;
    }
    ts.isComment = isComment;
    function isStringOrRegularExpressionOrTemplateLiteral(kind) {
        if (kind === 9 /* StringLiteral */
            || kind === 12 /* RegularExpressionLiteral */
            || ts.isTemplateLiteralKind(kind)) {
            return true;
        }
        return false;
    }
    ts.isStringOrRegularExpressionOrTemplateLiteral = isStringOrRegularExpressionOrTemplateLiteral;
    function isPunctuation(kind) {
        return 17 /* FirstPunctuation */ <= kind && kind <= 70 /* LastPunctuation */;
    }
    ts.isPunctuation = isPunctuation;
    function isInsideTemplateLiteral(node, position) {
        return ts.isTemplateLiteralKind(node.kind)
            && (node.getStart() < position && position < node.getEnd()) || (!!node.isUnterminated && position === node.getEnd());
    }
    ts.isInsideTemplateLiteral = isInsideTemplateLiteral;
    function isAccessibilityModifier(kind) {
        switch (kind) {
            case 114 /* PublicKeyword */:
            case 112 /* PrivateKeyword */:
            case 113 /* ProtectedKeyword */:
                return true;
        }
        return false;
    }
    ts.isAccessibilityModifier = isAccessibilityModifier;
    function cloneCompilerOptions(options) {
        var result = ts.clone(options);
        ts.setConfigFileInOptions(result, options && options.configFile);
        return result;
    }
    ts.cloneCompilerOptions = cloneCompilerOptions;
    function isArrayLiteralOrObjectLiteralDestructuringPattern(node) {
        if (node.kind === 177 /* ArrayLiteralExpression */ ||
            node.kind === 178 /* ObjectLiteralExpression */) {
            // [a,b,c] from:
            // [a, b, c] = someExpression;
            if (node.parent.kind === 194 /* BinaryExpression */ &&
                node.parent.left === node &&
                node.parent.operatorToken.kind === 58 /* EqualsToken */) {
                return true;
            }
            // [a, b, c] from:
            // for([a, b, c] of expression)
            if (node.parent.kind === 216 /* ForOfStatement */ &&
                node.parent.initializer === node) {
                return true;
            }
            // [a, b, c] of
            // [x, [a, b, c] ] = someExpression
            // or
            // {x, a: {a, b, c} } = someExpression
            if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === 261 /* PropertyAssignment */ ? node.parent.parent : node.parent)) {
                return true;
            }
        }
        return false;
    }
    ts.isArrayLiteralOrObjectLiteralDestructuringPattern = isArrayLiteralOrObjectLiteralDestructuringPattern;
    function hasTrailingDirectorySeparator(path) {
        var lastCharacter = path.charAt(path.length - 1);
        return lastCharacter === "/" || lastCharacter === "\\";
    }
    ts.hasTrailingDirectorySeparator = hasTrailingDirectorySeparator;
    function isInReferenceComment(sourceFile, position) {
        return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, function (c) {
            var commentText = sourceFile.text.substring(c.pos, c.end);
            return tripleSlashDirectivePrefixRegex.test(commentText);
        });
    }
    ts.isInReferenceComment = isInReferenceComment;
    function isInNonReferenceComment(sourceFile, position) {
        return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, function (c) {
            var commentText = sourceFile.text.substring(c.pos, c.end);
            return !tripleSlashDirectivePrefixRegex.test(commentText);
        });
    }
    ts.isInNonReferenceComment = isInNonReferenceComment;
    function createTextSpanFromNode(node, sourceFile) {
        return ts.createTextSpanFromBounds(node.getStart(sourceFile), node.getEnd());
    }
    ts.createTextSpanFromNode = createTextSpanFromNode;
    function createTextSpanFromRange(range) {
        return ts.createTextSpanFromBounds(range.pos, range.end);
    }
    ts.createTextSpanFromRange = createTextSpanFromRange;
    function isTypeKeyword(kind) {
        switch (kind) {
            case 119 /* AnyKeyword */:
            case 122 /* BooleanKeyword */:
            case 130 /* NeverKeyword */:
            case 133 /* NumberKeyword */:
            case 134 /* ObjectKeyword */:
            case 136 /* StringKeyword */:
            case 137 /* SymbolKeyword */:
            case 105 /* VoidKeyword */:
                return true;
            default:
                return false;
        }
    }
    ts.isTypeKeyword = isTypeKeyword;
    /** True if the symbol is for an external module, as opposed to a namespace. */
    function isExternalModuleSymbol(moduleSymbol) {
        ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
        return moduleSymbol.name.charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isExternalModuleSymbol = isExternalModuleSymbol;
    /** Returns `true` the first time it encounters a node and `false` afterwards. */
    function nodeSeenTracker() {
        var seen = [];
        return function (node) {
            var id = ts.getNodeId(node);
            return !seen[id] && (seen[id] = true);
        };
    }
    ts.nodeSeenTracker = nodeSeenTracker;
})(ts || (ts = {}));
// Display-part writer helpers
/* @internal */
(function (ts) {
    function isFirstDeclarationOfSymbolParameter(symbol) {
        return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 146 /* Parameter */;
    }
    ts.isFirstDeclarationOfSymbolParameter = isFirstDeclarationOfSymbolParameter;
    var displayPartWriter = getDisplayPartWriter();
    function getDisplayPartWriter() {
        var displayParts;
        var lineStart;
        var indent;
        resetWriter();
        return {
            displayParts: function () { return displayParts; },
            writeKeyword: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.keyword); },
            writeOperator: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.operator); },
            writePunctuation: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); },
            writeSpace: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.space); },
            writeStringLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); },
            writeParameter: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.parameterName); },
            writeProperty: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.propertyName); },
            writeSymbol: writeSymbol,
            writeLine: writeLine,
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            clear: resetWriter,
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
        function writeIndent() {
            if (lineStart) {
                var indentString = ts.getIndentString(indent);
                if (indentString) {
                    displayParts.push(displayPart(indentString, ts.SymbolDisplayPartKind.space));
                }
                lineStart = false;
            }
        }
        function writeKind(text, kind) {
            writeIndent();
            displayParts.push(displayPart(text, kind));
        }
        function writeSymbol(text, symbol) {
            writeIndent();
            displayParts.push(symbolPart(text, symbol));
        }
        function writeLine() {
            displayParts.push(lineBreakPart());
            lineStart = true;
        }
        function resetWriter() {
            displayParts = [];
            lineStart = true;
            indent = 0;
        }
    }
    function symbolPart(text, symbol) {
        return displayPart(text, displayPartKind(symbol));
        function displayPartKind(symbol) {
            var flags = symbol.flags;
            if (flags & 3 /* Variable */) {
                return isFirstDeclarationOfSymbolParameter(symbol) ? ts.SymbolDisplayPartKind.parameterName : ts.SymbolDisplayPartKind.localName;
            }
            else if (flags & 4 /* Property */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 32768 /* GetAccessor */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 65536 /* SetAccessor */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 8 /* EnumMember */) {
                return ts.SymbolDisplayPartKind.enumMemberName;
            }
            else if (flags & 16 /* Function */) {
                return ts.SymbolDisplayPartKind.functionName;
            }
            else if (flags & 32 /* Class */) {
                return ts.SymbolDisplayPartKind.className;
            }
            else if (flags & 64 /* Interface */) {
                return ts.SymbolDisplayPartKind.interfaceName;
            }
            else if (flags & 384 /* Enum */) {
                return ts.SymbolDisplayPartKind.enumName;
            }
            else if (flags & 1536 /* Module */) {
                return ts.SymbolDisplayPartKind.moduleName;
            }
            else if (flags & 8192 /* Method */) {
                return ts.SymbolDisplayPartKind.methodName;
            }
            else if (flags & 262144 /* TypeParameter */) {
                return ts.SymbolDisplayPartKind.typeParameterName;
            }
            else if (flags & 524288 /* TypeAlias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            else if (flags & 2097152 /* Alias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            return ts.SymbolDisplayPartKind.text;
        }
    }
    ts.symbolPart = symbolPart;
    function displayPart(text, kind) {
        return { text: text, kind: ts.SymbolDisplayPartKind[kind] };
    }
    ts.displayPart = displayPart;
    function spacePart() {
        return displayPart(" ", ts.SymbolDisplayPartKind.space);
    }
    ts.spacePart = spacePart;
    function keywordPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.keyword);
    }
    ts.keywordPart = keywordPart;
    function punctuationPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.punctuation);
    }
    ts.punctuationPart = punctuationPart;
    function operatorPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.operator);
    }
    ts.operatorPart = operatorPart;
    function textOrKeywordPart(text) {
        var kind = ts.stringToToken(text);
        return kind === undefined
            ? textPart(text)
            : keywordPart(kind);
    }
    ts.textOrKeywordPart = textOrKeywordPart;
    function textPart(text) {
        return displayPart(text, ts.SymbolDisplayPartKind.text);
    }
    ts.textPart = textPart;
    var carriageReturnLineFeed = "\r\n";
    /**
     * The default is CRLF.
     */
    function getNewLineOrDefaultFromHost(host) {
        return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed;
    }
    ts.getNewLineOrDefaultFromHost = getNewLineOrDefaultFromHost;
    function lineBreakPart() {
        return displayPart("\n", ts.SymbolDisplayPartKind.lineBreak);
    }
    ts.lineBreakPart = lineBreakPart;
    function mapToDisplayParts(writeDisplayParts) {
        try {
            writeDisplayParts(displayPartWriter);
            return displayPartWriter.displayParts();
        }
        finally {
            displayPartWriter.clear();
        }
    }
    ts.mapToDisplayParts = mapToDisplayParts;
    function typeToDisplayParts(typechecker, type, enclosingDeclaration, flags) {
        return mapToDisplayParts(function (writer) {
            typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
        });
    }
    ts.typeToDisplayParts = typeToDisplayParts;
    function symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration, meaning, flags) {
        return mapToDisplayParts(function (writer) {
            typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags);
        });
    }
    ts.symbolToDisplayParts = symbolToDisplayParts;
    function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) {
        flags |= 65536 /* UseAliasDefinedOutsideCurrentScope */;
        return mapToDisplayParts(function (writer) {
            typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags);
        });
    }
    ts.signatureToDisplayParts = signatureToDisplayParts;
    function getDeclaredName(typeChecker, symbol, location) {
        // If this is an export or import specifier it could have been renamed using the 'as' syntax.
        // If so we want to search for whatever is under the cursor.
        if (isImportOrExportSpecifierName(location) || ts.isStringOrNumericLiteral(location) && location.parent.kind === 144 /* ComputedPropertyName */) {
            return ts.getTextOfIdentifierOrLiteral(location);
        }
        // Try to get the local symbol if we're dealing with an 'export default'
        // since that symbol has the "true" name.
        var localExportDefaultSymbol = ts.getLocalSymbolForExportDefault(symbol);
        return typeChecker.symbolToString(localExportDefaultSymbol || symbol);
    }
    ts.getDeclaredName = getDeclaredName;
    function isImportOrExportSpecifierName(location) {
        return location.parent &&
            (location.parent.kind === 242 /* ImportSpecifier */ || location.parent.kind === 246 /* ExportSpecifier */) &&
            location.parent.propertyName === location;
    }
    ts.isImportOrExportSpecifierName = isImportOrExportSpecifierName;
    /**
     * Strip off existed single quotes or double quotes from a given string
     *
     * @return non-quoted string
     */
    function stripQuotes(name) {
        var length = name.length;
        if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && ts.isSingleOrDoubleQuote(name.charCodeAt(0))) {
            return name.substring(1, length - 1);
        }
        return name;
    }
    ts.stripQuotes = stripQuotes;
    function scriptKindIs(fileName, host) {
        var scriptKinds = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            scriptKinds[_i - 2] = arguments[_i];
        }
        var scriptKind = getScriptKind(fileName, host);
        return ts.forEach(scriptKinds, function (k) { return k === scriptKind; });
    }
    ts.scriptKindIs = scriptKindIs;
    function getScriptKind(fileName, host) {
        // First check to see if the script kind was specified by the host. Chances are the host
        // may override the default script kind for the file extension.
        return ts.ensureScriptKind(fileName, host && host.getScriptKind && host.getScriptKind(fileName));
    }
    ts.getScriptKind = getScriptKind;
    function getUniqueSymbolId(symbol, checker) {
        return ts.getSymbolId(ts.skipAlias(symbol, checker));
    }
    ts.getUniqueSymbolId = getUniqueSymbolId;
    function getFirstNonSpaceCharacterPosition(text, position) {
        while (ts.isWhiteSpaceLike(text.charCodeAt(position))) {
            position += 1;
        }
        return position;
    }
    ts.getFirstNonSpaceCharacterPosition = getFirstNonSpaceCharacterPosition;
    function getOpenBrace(constructor, sourceFile) {
        // First token is the open curly, this is where we want to put the 'super' call.
        return constructor.body.getFirstToken(sourceFile);
    }
    ts.getOpenBrace = getOpenBrace;
    function getOpenBraceOfClassLike(declaration, sourceFile) {
        return ts.getTokenAtPosition(sourceFile, declaration.members.pos - 1, /*includeJsDocComment*/ false);
    }
    ts.getOpenBraceOfClassLike = getOpenBraceOfClassLike;
    function getSourceFileImportLocation(node) {
        // For a source file, it is possible there are detached comments we should not skip
        var text = node.text;
        var ranges = ts.getLeadingCommentRanges(text, 0);
        if (!ranges)
            return 0;
        var position = 0;
        // However we should still skip a pinned comment at the top
        if (ranges.length && ranges[0].kind === 3 /* MultiLineCommentTrivia */ && ts.isPinnedComment(text, ranges[0])) {
            position = ranges[0].end + 1;
            ranges = ranges.slice(1);
        }
        // As well as any triple slash references
        for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) {
            var range = ranges_1[_i];
            if (range.kind === 2 /* SingleLineCommentTrivia */ && ts.isRecognizedTripleSlashComment(node.text, range.pos, range.end)) {
                position = range.end + 1;
                continue;
            }
            break;
        }
        return position;
    }
    ts.getSourceFileImportLocation = getSourceFileImportLocation;
    /**
     * Creates a deep, memberwise clone of a node with no source map location.
     *
     * WARNING: This is an expensive operation and is only intended to be used in refactorings
     * and code fixes (because those are triggered by explicit user actions).
     */
    function getSynthesizedDeepClone(node) {
        if (node === undefined) {
            return undefined;
        }
        var visited = ts.visitEachChild(node, getSynthesizedDeepClone, ts.nullTransformationContext);
        if (visited === node) {
            // This only happens for leaf nodes - internal nodes always see their children change.
            var clone_7 = ts.getSynthesizedClone(node);
            if (ts.isStringLiteral(clone_7)) {
                clone_7.textSourceNode = node;
            }
            else if (ts.isNumericLiteral(clone_7)) {
                clone_7.numericLiteralFlags = node.numericLiteralFlags;
            }
            clone_7.pos = node.pos;
            clone_7.end = node.end;
            return clone_7;
        }
        // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update
        // the new node created by visitEachChild with the extra changes getSynthesizedClone
        // would have made.
        visited.parent = undefined;
        return visited;
    }
    ts.getSynthesizedDeepClone = getSynthesizedDeepClone;
    /**
     * Sets EmitFlags to suppress leading and trailing trivia on the node.
     */
    /* @internal */
    function suppressLeadingAndTrailingTrivia(node) {
        ts.Debug.assert(node !== undefined);
        suppressLeading(node);
        suppressTrailing(node);
        function suppressLeading(node) {
            ts.addEmitFlags(node, 512 /* NoLeadingComments */);
            var firstChild = ts.forEachChild(node, function (child) { return child; });
            firstChild && suppressLeading(firstChild);
        }
        function suppressTrailing(node) {
            ts.addEmitFlags(node, 1024 /* NoTrailingComments */);
            var lastChild = undefined;
            ts.forEachChild(node, function (child) { return (lastChild = child, undefined); }, function (children) {
                // As an optimization, jump straight to the end of the list.
                if (children.length) {
                    lastChild = ts.last(children);
                }
                return undefined;
            });
            lastChild && suppressTrailing(lastChild);
        }
    }
    ts.suppressLeadingAndTrailingTrivia = suppressLeadingAndTrailingTrivia;
})(ts || (ts = {}));
var ts;
(function (ts) {
    /// Classifier
    function createClassifier() {
        var scanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false);
        /// We do not have a full parser support to know when we should parse a regex or not
        /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
        /// we have a series of divide operator. this list allows us to be more accurate by ruling out
        /// locations where a regexp cannot exist.
        var noRegexTable = [];
        noRegexTable[71 /* Identifier */] = true;
        noRegexTable[9 /* StringLiteral */] = true;
        noRegexTable[8 /* NumericLiteral */] = true;
        noRegexTable[12 /* RegularExpressionLiteral */] = true;
        noRegexTable[99 /* ThisKeyword */] = true;
        noRegexTable[43 /* PlusPlusToken */] = true;
        noRegexTable[44 /* MinusMinusToken */] = true;
        noRegexTable[20 /* CloseParenToken */] = true;
        noRegexTable[22 /* CloseBracketToken */] = true;
        noRegexTable[18 /* CloseBraceToken */] = true;
        noRegexTable[101 /* TrueKeyword */] = true;
        noRegexTable[86 /* FalseKeyword */] = true;
        // Just a stack of TemplateHeads and OpenCurlyBraces, used to perform rudimentary (inexact)
        // classification on template strings. Because of the context free nature of templates,
        // the only precise way to classify a template portion would be by propagating the stack across
        // lines, just as we do with the end-of-line state. However, this is a burden for implementers,
        // and the behavior is entirely subsumed by the syntactic classifier anyway, so we instead
        // flatten any nesting when the template stack is non-empty and encode it in the end-of-line state.
        // Situations in which this fails are
        //  1) When template strings are nested across different lines:
        //          `hello ${ `world
        //          ` }`
        //
        //     Where on the second line, you will get the closing of a template,
        //     a closing curly, and a new template.
        //
        //  2) When substitution expressions have curly braces and the curly brace falls on the next line:
        //          `hello ${ () => {
        //          return "world" } } `
        //
        //     Where on the second line, you will get the 'return' keyword,
        //     a string literal, and a template end consisting of '} } `'.
        var templateStack = [];
        /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
        function canFollow(keyword1, keyword2) {
            if (ts.isAccessibilityModifier(keyword1)) {
                if (keyword2 === 125 /* GetKeyword */ ||
                    keyword2 === 135 /* SetKeyword */ ||
                    keyword2 === 123 /* ConstructorKeyword */ ||
                    keyword2 === 115 /* StaticKeyword */) {
                    // Allow things like "public get", "public constructor" and "public static".
                    // These are all legal.
                    return true;
                }
                // Any other keyword following "public" is actually an identifier an not a real
                // keyword.
                return false;
            }
            // Assume any other keyword combination is legal.  This can be refined in the future
            // if there are more cases we want the classifier to be better at.
            return true;
        }
        function convertClassifications(classifications, text) {
            var entries = [];
            var dense = classifications.spans;
            var lastEnd = 0;
            for (var i = 0; i < dense.length; i += 3) {
                var start = dense[i];
                var length_6 = dense[i + 1];
                var type = dense[i + 2];
                // Make a whitespace entry between the last item and this one.
                if (lastEnd >= 0) {
                    var whitespaceLength_1 = start - lastEnd;
                    if (whitespaceLength_1 > 0) {
                        entries.push({ length: whitespaceLength_1, classification: ts.TokenClass.Whitespace });
                    }
                }
                entries.push({ length: length_6, classification: convertClassification(type) });
                lastEnd = start + length_6;
            }
            var whitespaceLength = text.length - lastEnd;
            if (whitespaceLength > 0) {
                entries.push({ length: whitespaceLength, classification: ts.TokenClass.Whitespace });
            }
            return { entries: entries, finalLexState: classifications.endOfLineState };
        }
        function convertClassification(type) {
            switch (type) {
                case 1 /* comment */: return ts.TokenClass.Comment;
                case 3 /* keyword */: return ts.TokenClass.Keyword;
                case 4 /* numericLiteral */: return ts.TokenClass.NumberLiteral;
                case 5 /* operator */: return ts.TokenClass.Operator;
                case 6 /* stringLiteral */: return ts.TokenClass.StringLiteral;
                case 8 /* whiteSpace */: return ts.TokenClass.Whitespace;
                case 10 /* punctuation */: return ts.TokenClass.Punctuation;
                case 2 /* identifier */:
                case 11 /* className */:
                case 12 /* enumName */:
                case 13 /* interfaceName */:
                case 14 /* moduleName */:
                case 15 /* typeParameterName */:
                case 16 /* typeAliasName */:
                case 9 /* text */:
                case 17 /* parameterName */:
                default:
                    return ts.TokenClass.Identifier;
            }
        }
        function getClassificationsForLine(text, lexState, syntacticClassifierAbsent) {
            return convertClassifications(getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent), text);
        }
        // If there is a syntactic classifier ('syntacticClassifierAbsent' is false),
        // we will be more conservative in order to avoid conflicting with the syntactic classifier.
        function getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent) {
            var offset = 0;
            var token = 0 /* Unknown */;
            var lastNonTriviaToken = 0 /* Unknown */;
            // Empty out the template stack for reuse.
            while (templateStack.length > 0) {
                templateStack.pop();
            }
            // If we're in a string literal, then prepend: "\
            // (and a newline).  That way when we lex we'll think we're still in a string literal.
            //
            // If we're in a multiline comment, then prepend: /*
            // (and a newline).  That way when we lex we'll think we're still in a multiline comment.
            switch (lexState) {
                case 3 /* InDoubleQuoteStringLiteral */:
                    text = "\"\\\n" + text;
                    offset = 3;
                    break;
                case 2 /* InSingleQuoteStringLiteral */:
                    text = "'\\\n" + text;
                    offset = 3;
                    break;
                case 1 /* InMultiLineCommentTrivia */:
                    text = "/*\n" + text;
                    offset = 3;
                    break;
                case 4 /* InTemplateHeadOrNoSubstitutionTemplate */:
                    text = "`\n" + text;
                    offset = 2;
                    break;
                case 5 /* InTemplateMiddleOrTail */:
                    text = "}\n" + text;
                    offset = 2;
                // falls through
                case 6 /* InTemplateSubstitutionPosition */:
                    templateStack.push(14 /* TemplateHead */);
                    break;
            }
            scanner.setText(text);
            var result = {
                endOfLineState: 0 /* None */,
                spans: []
            };
            // We can run into an unfortunate interaction between the lexical and syntactic classifier
            // when the user is typing something generic.  Consider the case where the user types:
            //
            //      Foo<number
            //
            // From the lexical classifier's perspective, 'number' is a keyword, and so the word will
            // be classified as such.  However, from the syntactic classifier's tree-based perspective
            // this is simply an expression with the identifier 'number' on the RHS of the less than
            // token.  So the classification will go back to being an identifier.  The moment the user
            // types again, number will become a keyword, then an identifier, etc. etc.
            //
            // To try to avoid this problem, we avoid classifying contextual keywords as keywords
            // when the user is potentially typing something generic.  We just can't do a good enough
            // job at the lexical level, and so well leave it up to the syntactic classifier to make
            // the determination.
            //
            // In order to determine if the user is potentially typing something generic, we use a
            // weak heuristic where we track < and > tokens.  It's a weak heuristic, but should
            // work well enough in practice.
            var angleBracketStack = 0;
            do {
                token = scanner.scan();
                if (!ts.isTrivia(token)) {
                    if ((token === 41 /* SlashToken */ || token === 63 /* SlashEqualsToken */) && !noRegexTable[lastNonTriviaToken]) {
                        if (scanner.reScanSlashToken() === 12 /* RegularExpressionLiteral */) {
                            token = 12 /* RegularExpressionLiteral */;
                        }
                    }
                    else if (lastNonTriviaToken === 23 /* DotToken */ && isKeyword(token)) {
                        token = 71 /* Identifier */;
                    }
                    else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
                        // We have two keywords in a row.  Only treat the second as a keyword if
                        // it's a sequence that could legally occur in the language.  Otherwise
                        // treat it as an identifier.  This way, if someone writes "private var"
                        // we recognize that 'var' is actually an identifier here.
                        token = 71 /* Identifier */;
                    }
                    else if (lastNonTriviaToken === 71 /* Identifier */ &&
                        token === 27 /* LessThanToken */) {
                        // Could be the start of something generic.  Keep track of that by bumping
                        // up the current count of generic contexts we may be in.
                        angleBracketStack++;
                    }
                    else if (token === 29 /* GreaterThanToken */ && angleBracketStack > 0) {
                        // If we think we're currently in something generic, then mark that that
                        // generic entity is complete.
                        angleBracketStack--;
                    }
                    else if (token === 119 /* AnyKeyword */ ||
                        token === 136 /* StringKeyword */ ||
                        token === 133 /* NumberKeyword */ ||
                        token === 122 /* BooleanKeyword */ ||
                        token === 137 /* SymbolKeyword */) {
                        if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
                            // If it looks like we're could be in something generic, don't classify this
                            // as a keyword.  We may just get overwritten by the syntactic classifier,
                            // causing a noisy experience for the user.
                            token = 71 /* Identifier */;
                        }
                    }
                    else if (token === 14 /* TemplateHead */) {
                        templateStack.push(token);
                    }
                    else if (token === 17 /* OpenBraceToken */) {
                        // If we don't have anything on the template stack,
                        // then we aren't trying to keep track of a previously scanned template head.
                        if (templateStack.length > 0) {
                            templateStack.push(token);
                        }
                    }
                    else if (token === 18 /* CloseBraceToken */) {
                        // If we don't have anything on the template stack,
                        // then we aren't trying to keep track of a previously scanned template head.
                        if (templateStack.length > 0) {
                            var lastTemplateStackToken = ts.lastOrUndefined(templateStack);
                            if (lastTemplateStackToken === 14 /* TemplateHead */) {
                                token = scanner.reScanTemplateToken();
                                // Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us.
                                if (token === 16 /* TemplateTail */) {
                                    templateStack.pop();
                                }
                                else {
                                    ts.Debug.assertEqual(token, 15 /* TemplateMiddle */, "Should have been a template middle.");
                                }
                            }
                            else {
                                ts.Debug.assertEqual(lastTemplateStackToken, 17 /* OpenBraceToken */, "Should have been an open brace");
                                templateStack.pop();
                            }
                        }
                    }
                    lastNonTriviaToken = token;
                }
                processToken();
            } while (token !== 1 /* EndOfFileToken */);
            return result;
            function processToken() {
                var start = scanner.getTokenPos();
                var end = scanner.getTextPos();
                addResult(start, end, classFromKind(token));
                if (end >= text.length) {
                    if (token === 9 /* StringLiteral */) {
                        // Check to see if we finished up on a multiline string literal.
                        var tokenText = scanner.getTokenText();
                        if (scanner.isUnterminated()) {
                            var lastCharIndex = tokenText.length - 1;
                            var numBackslashes = 0;
                            while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === 92 /* backslash */) {
                                numBackslashes++;
                            }
                            // If we have an odd number of backslashes, then the multiline string is unclosed
                            if (numBackslashes & 1) {
                                var quoteChar = tokenText.charCodeAt(0);
                                result.endOfLineState = quoteChar === 34 /* doubleQuote */
                                    ? 3 /* InDoubleQuoteStringLiteral */
                                    : 2 /* InSingleQuoteStringLiteral */;
                            }
                        }
                    }
                    else if (token === 3 /* MultiLineCommentTrivia */) {
                        // Check to see if the multiline comment was unclosed.
                        if (scanner.isUnterminated()) {
                            result.endOfLineState = 1 /* InMultiLineCommentTrivia */;
                        }
                    }
                    else if (ts.isTemplateLiteralKind(token)) {
                        if (scanner.isUnterminated()) {
                            if (token === 16 /* TemplateTail */) {
                                result.endOfLineState = 5 /* InTemplateMiddleOrTail */;
                            }
                            else if (token === 13 /* NoSubstitutionTemplateLiteral */) {
                                result.endOfLineState = 4 /* InTemplateHeadOrNoSubstitutionTemplate */;
                            }
                            else {
                                ts.Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token);
                            }
                        }
                    }
                    else if (templateStack.length > 0 && ts.lastOrUndefined(templateStack) === 14 /* TemplateHead */) {
                        result.endOfLineState = 6 /* InTemplateSubstitutionPosition */;
                    }
                }
            }
            function addResult(start, end, classification) {
                if (classification === 8 /* whiteSpace */) {
                    // Don't bother with whitespace classifications.  They're not needed.
                    return;
                }
                if (start === 0 && offset > 0) {
                    // We're classifying the first token, and this was a case where we prepended
                    // text.  We should consider the start of this token to be at the start of
                    // the original text.
                    start += offset;
                }
                // All our tokens are in relation to the augmented text.  Move them back to be
                // relative to the original text.
                start -= offset;
                end -= offset;
                var length = end - start;
                if (length > 0) {
                    result.spans.push(start);
                    result.spans.push(length);
                    result.spans.push(classification);
                }
            }
        }
        function isBinaryExpressionOperatorToken(token) {
            switch (token) {
                case 39 /* AsteriskToken */:
                case 41 /* SlashToken */:
                case 42 /* PercentToken */:
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                case 45 /* LessThanLessThanToken */:
                case 46 /* GreaterThanGreaterThanToken */:
                case 47 /* GreaterThanGreaterThanGreaterThanToken */:
                case 27 /* LessThanToken */:
                case 29 /* GreaterThanToken */:
                case 30 /* LessThanEqualsToken */:
                case 31 /* GreaterThanEqualsToken */:
                case 93 /* InstanceOfKeyword */:
                case 92 /* InKeyword */:
                case 118 /* AsKeyword */:
                case 32 /* EqualsEqualsToken */:
                case 33 /* ExclamationEqualsToken */:
                case 34 /* EqualsEqualsEqualsToken */:
                case 35 /* ExclamationEqualsEqualsToken */:
                case 48 /* AmpersandToken */:
                case 50 /* CaretToken */:
                case 49 /* BarToken */:
                case 53 /* AmpersandAmpersandToken */:
                case 54 /* BarBarToken */:
                case 69 /* BarEqualsToken */:
                case 68 /* AmpersandEqualsToken */:
                case 70 /* CaretEqualsToken */:
                case 65 /* LessThanLessThanEqualsToken */:
                case 66 /* GreaterThanGreaterThanEqualsToken */:
                case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 59 /* PlusEqualsToken */:
                case 60 /* MinusEqualsToken */:
                case 61 /* AsteriskEqualsToken */:
                case 63 /* SlashEqualsToken */:
                case 64 /* PercentEqualsToken */:
                case 58 /* EqualsToken */:
                case 26 /* CommaToken */:
                    return true;
                default:
                    return false;
            }
        }
        function isPrefixUnaryExpressionOperatorToken(token) {
            switch (token) {
                case 37 /* PlusToken */:
                case 38 /* MinusToken */:
                case 52 /* TildeToken */:
                case 51 /* ExclamationToken */:
                case 43 /* PlusPlusToken */:
                case 44 /* MinusMinusToken */:
                    return true;
                default:
                    return false;
            }
        }
        function isKeyword(token) {
            return token >= 72 /* FirstKeyword */ && token <= 142 /* LastKeyword */;
        }
        function classFromKind(token) {
            if (isKeyword(token)) {
                return 3 /* keyword */;
            }
            else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
                return 5 /* operator */;
            }
            else if (token >= 17 /* FirstPunctuation */ && token <= 70 /* LastPunctuation */) {
                return 10 /* punctuation */;
            }
            switch (token) {
                case 8 /* NumericLiteral */:
                    return 4 /* numericLiteral */;
                case 9 /* StringLiteral */:
                    return 6 /* stringLiteral */;
                case 12 /* RegularExpressionLiteral */:
                    return 7 /* regularExpressionLiteral */;
                case 7 /* ConflictMarkerTrivia */:
                case 3 /* MultiLineCommentTrivia */:
                case 2 /* SingleLineCommentTrivia */:
                    return 1 /* comment */;
                case 5 /* WhitespaceTrivia */:
                case 4 /* NewLineTrivia */:
                    return 8 /* whiteSpace */;
                case 71 /* Identifier */:
                default:
                    if (ts.isTemplateLiteralKind(token)) {
                        return 6 /* stringLiteral */;
                    }
                    return 2 /* identifier */;
            }
        }
        return {
            getClassificationsForLine: getClassificationsForLine,
            getEncodedLexicalClassifications: getEncodedLexicalClassifications
        };
    }
    ts.createClassifier = createClassifier;
    /* @internal */
    function getSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
        return convertClassifications(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
    }
    ts.getSemanticClassifications = getSemanticClassifications;
    function checkForClassificationCancellation(cancellationToken, kind) {
        // We don't want to actually call back into our host on every node to find out if we've
        // been canceled.  That would be an enormous amount of chattyness, along with the all
        // the overhead of marshalling the data to/from the host.  So instead we pick a few
        // reasonable node kinds to bother checking on.  These node kinds represent high level
        // constructs that we would expect to see commonly, but just at a far less frequent
        // interval.
        //
        // For example, in checker.ts (around 750k) we only have around 600 of these constructs.
        // That means we're calling back into the host around every 1.2k of the file we process.
        // Lib.d.ts has similar numbers.
        switch (kind) {
            case 233 /* ModuleDeclaration */:
            case 229 /* ClassDeclaration */:
            case 230 /* InterfaceDeclaration */:
            case 228 /* FunctionDeclaration */:
                cancellationToken.throwIfCancellationRequested();
        }
    }
    /* @internal */
    function getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
        var result = [];
        processNode(sourceFile);
        return { spans: result, endOfLineState: 0 /* None */ };
        function pushClassification(start, length, type) {
            result.push(start);
            result.push(length);
            result.push(type);
        }
        function classifySymbol(symbol, meaningAtPosition) {
            var flags = symbol.getFlags();
            if ((flags & 788448 /* Classifiable */) === 0 /* None */) {
                return;
            }
            if (flags & 32 /* Class */) {
                return 11 /* className */;
            }
            else if (flags & 384 /* Enum */) {
                return 12 /* enumName */;
            }
            else if (flags & 524288 /* TypeAlias */) {
                return 16 /* typeAliasName */;
            }
            else if (meaningAtPosition & 2 /* Type */) {
                if (flags & 64 /* Interface */) {
                    return 13 /* interfaceName */;
                }
                else if (flags & 262144 /* TypeParameter */) {
                    return 15 /* typeParameterName */;
                }
            }
            else if (flags & 1536 /* Module */) {
                // Only classify a module as such if
                //  - It appears in a namespace context.
                //  - There exists a module declaration which actually impacts the value side.
                if (meaningAtPosition & 4 /* Namespace */ ||
                    (meaningAtPosition & 1 /* Value */ && hasValueSideModule(symbol))) {
                    return 14 /* moduleName */;
                }
            }
            return undefined;
            /**
             * Returns true if there exists a module that introduces entities on the value side.
             */
            function hasValueSideModule(symbol) {
                return ts.forEach(symbol.declarations, function (declaration) {
                    return declaration.kind === 233 /* ModuleDeclaration */ &&
                        ts.getModuleInstanceState(declaration) === 1 /* Instantiated */;
                });
            }
        }
        function processNode(node) {
            // Only walk into nodes that intersect the requested span.
            if (node && ts.textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) {
                var kind = node.kind;
                checkForClassificationCancellation(cancellationToken, kind);
                if (kind === 71 /* Identifier */ && !ts.nodeIsMissing(node)) {
                    var identifier = node;
                    // Only bother calling into the typechecker if this is an identifier that
                    // could possibly resolve to a type name.  This makes classification run
                    // in a third of the time it would normally take.
                    if (classifiableNames.has(identifier.escapedText)) {
                        var symbol = typeChecker.getSymbolAtLocation(node);
                        if (symbol) {
                            var type = classifySymbol(symbol, ts.getMeaningFromLocation(node));
                            if (type) {
                                pushClassification(node.getStart(), node.getWidth(), type);
                            }
                        }
                    }
                }
                ts.forEachChild(node, processNode);
            }
        }
    }
    ts.getEncodedSemanticClassifications = getEncodedSemanticClassifications;
    function getClassificationTypeName(type) {
        switch (type) {
            case 1 /* comment */: return "comment" /* comment */;
            case 2 /* identifier */: return "identifier" /* identifier */;
            case 3 /* keyword */: return "keyword" /* keyword */;
            case 4 /* numericLiteral */: return "number" /* numericLiteral */;
            case 5 /* operator */: return "operator" /* operator */;
            case 6 /* stringLiteral */: return "string" /* stringLiteral */;
            case 8 /* whiteSpace */: return "whitespace" /* whiteSpace */;
            case 9 /* text */: return "text" /* text */;
            case 10 /* punctuation */: return "punctuation" /* punctuation */;
            case 11 /* className */: return "class name" /* className */;
            case 12 /* enumName */: return "enum name" /* enumName */;
            case 13 /* interfaceName */: return "interface name" /* interfaceName */;
            case 14 /* moduleName */: return "module name" /* moduleName */;
            case 15 /* typeParameterName */: return "type parameter name" /* typeParameterName */;
            case 16 /* typeAliasName */: return "type alias name" /* typeAliasName */;
            case 17 /* parameterName */: return "parameter name" /* parameterName */;
            case 18 /* docCommentTagName */: return "doc comment tag name" /* docCommentTagName */;
            case 19 /* jsxOpenTagName */: return "jsx open tag name" /* jsxOpenTagName */;
            case 20 /* jsxCloseTagName */: return "jsx close tag name" /* jsxCloseTagName */;
            case 21 /* jsxSelfClosingTagName */: return "jsx self closing tag name" /* jsxSelfClosingTagName */;
            case 22 /* jsxAttribute */: return "jsx attribute" /* jsxAttribute */;
            case 23 /* jsxText */: return "jsx text" /* jsxText */;
            case 24 /* jsxAttributeStringLiteralValue */: return "jsx attribute string literal value" /* jsxAttributeStringLiteralValue */;
        }
    }
    function convertClassifications(classifications) {
        ts.Debug.assert(classifications.spans.length % 3 === 0);
        var dense = classifications.spans;
        var result = [];
        for (var i = 0; i < dense.length; i += 3) {
            result.push({
                textSpan: ts.createTextSpan(dense[i], dense[i + 1]),
                classificationType: getClassificationTypeName(dense[i + 2])
            });
        }
        return result;
    }
    /* @internal */
    function getSyntacticClassifications(cancellationToken, sourceFile, span) {
        return convertClassifications(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span));
    }
    ts.getSyntacticClassifications = getSyntacticClassifications;
    /* @internal */
    function getEncodedSyntacticClassifications(cancellationToken, sourceFile, span) {
        var spanStart = span.start;
        var spanLength = span.length;
        // Make a scanner we can get trivia from.
        var triviaScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
        var mergeConflictScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
        var result = [];
        processElement(sourceFile);
        return { spans: result, endOfLineState: 0 /* None */ };
        function pushClassification(start, length, type) {
            result.push(start);
            result.push(length);
            result.push(type);
        }
        function classifyLeadingTriviaAndGetTokenStart(token) {
            triviaScanner.setTextPos(token.pos);
            while (true) {
                var start = triviaScanner.getTextPos();
                // only bother scanning if we have something that could be trivia.
                if (!ts.couldStartTrivia(sourceFile.text, start)) {
                    return start;
                }
                var kind = triviaScanner.scan();
                var end = triviaScanner.getTextPos();
                var width = end - start;
                // The moment we get something that isn't trivia, then stop processing.
                if (!ts.isTrivia(kind)) {
                    return start;
                }
                // Don't bother with newlines/whitespace.
                if (kind === 4 /* NewLineTrivia */ || kind === 5 /* WhitespaceTrivia */) {
                    continue;
                }
                // Only bother with the trivia if it at least intersects the span of interest.
                if (ts.isComment(kind)) {
                    classifyComment(token, kind, start, width);
                    // Classifying a comment might cause us to reuse the trivia scanner
                    // (because of jsdoc comments).  So after we classify the comment make
                    // sure we set the scanner position back to where it needs to be.
                    triviaScanner.setTextPos(end);
                    continue;
                }
                if (kind === 7 /* ConflictMarkerTrivia */) {
                    var text = sourceFile.text;
                    var ch = text.charCodeAt(start);
                    // for the <<<<<<< and >>>>>>> markers, we just add them in as comments
                    // in the classification stream.
                    if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
                        pushClassification(start, width, 1 /* comment */);
                        continue;
                    }
                    // for the ||||||| and ======== markers, add a comment for the first line,
                    // and then lex all subsequent lines up until the end of the conflict marker.
                    ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
                    classifyDisabledMergeCode(text, start, end);
                }
            }
        }
        function classifyComment(token, kind, start, width) {
            if (kind === 3 /* MultiLineCommentTrivia */) {
                // See if this is a doc comment.  If so, we'll classify certain portions of it
                // specially.
                var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width);
                if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) {
                    // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]`
                    docCommentAndDiagnostics.jsDoc.parent = token;
                    classifyJSDocComment(docCommentAndDiagnostics.jsDoc);
                    return;
                }
            }
            // Simple comment.  Just add as is.
            pushCommentRange(start, width);
        }
        function pushCommentRange(start, width) {
            pushClassification(start, width, 1 /* comment */);
        }
        function classifyJSDocComment(docComment) {
            var pos = docComment.pos;
            if (docComment.tags) {
                for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) {
                    var tag = _a[_i];
                    // As we walk through each tag, classify the portion of text from the end of
                    // the last tag (or the start of the entire doc comment) as 'comment'.
                    if (tag.pos !== pos) {
                        pushCommentRange(pos, tag.pos - pos);
                    }
                    pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, 10 /* punctuation */); // "@"
                    pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); // e.g. "param"
                    pos = tag.tagName.end;
                    switch (tag.kind) {
                        case 279 /* JSDocParameterTag */:
                            processJSDocParameterTag(tag);
                            break;
                        case 282 /* JSDocTemplateTag */:
                            processJSDocTemplateTag(tag);
                            break;
                        case 281 /* JSDocTypeTag */:
                            processElement(tag.typeExpression);
                            break;
                        case 280 /* JSDocReturnTag */:
                            processElement(tag.typeExpression);
                            break;
                    }
                    pos = tag.end;
                }
            }
            if (pos !== docComment.end) {
                pushCommentRange(pos, docComment.end - pos);
            }
            return;
            function processJSDocParameterTag(tag) {
                if (tag.isNameFirst) {
                    pushCommentRange(pos, tag.name.pos - pos);
                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
                    pos = tag.name.end;
                }
                if (tag.typeExpression) {
                    pushCommentRange(pos, tag.typeExpression.pos - pos);
                    processElement(tag.typeExpression);
                    pos = tag.typeExpression.end;
                }
                if (!tag.isNameFirst) {
                    pushCommentRange(pos, tag.name.pos - pos);
                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
                    pos = tag.name.end;
                }
            }
        }
        function processJSDocTemplateTag(tag) {
            for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                processElement(child);
            }
        }
        function classifyDisabledMergeCode(text, start, end) {
            // Classify the line that the ||||||| or ======= marker is on as a comment.
            // Then just lex all further tokens and add them to the result.
            var i;
            for (i = start; i < end; i++) {
                if (ts.isLineBreak(text.charCodeAt(i))) {
                    break;
                }
            }
            pushClassification(start, i - start, 1 /* comment */);
            mergeConflictScanner.setTextPos(i);
            while (mergeConflictScanner.getTextPos() < end) {
                classifyDisabledCodeToken();
            }
        }
        function classifyDisabledCodeToken() {
            var start = mergeConflictScanner.getTextPos();
            var tokenKind = mergeConflictScanner.scan();
            var end = mergeConflictScanner.getTextPos();
            var type = classifyTokenType(tokenKind);
            if (type) {
                pushClassification(start, end - start, type);
            }
        }
        /**
         * Returns true if node should be treated as classified and no further processing is required.
         * False will mean that node is not classified and traverse routine should recurse into node contents.
         */
        function tryClassifyNode(node) {
            if (ts.isJSDoc(node)) {
                return true;
            }
            if (ts.nodeIsMissing(node)) {
                return true;
            }
            var classifiedElementName = tryClassifyJsxElementName(node);
            if (!ts.isToken(node) && node.kind !== 10 /* JsxText */ && classifiedElementName === undefined) {
                return false;
            }
            var tokenStart = node.kind === 10 /* JsxText */ ? node.pos : classifyLeadingTriviaAndGetTokenStart(node);
            var tokenWidth = node.end - tokenStart;
            ts.Debug.assert(tokenWidth >= 0);
            if (tokenWidth > 0) {
                var type = classifiedElementName || classifyTokenType(node.kind, node);
                if (type) {
                    pushClassification(tokenStart, tokenWidth, type);
                }
            }
            return true;
        }
        function tryClassifyJsxElementName(token) {
            switch (token.parent && token.parent.kind) {
                case 251 /* JsxOpeningElement */:
                    if (token.parent.tagName === token) {
                        return 19 /* jsxOpenTagName */;
                    }
                    break;
                case 252 /* JsxClosingElement */:
                    if (token.parent.tagName === token) {
                        return 20 /* jsxCloseTagName */;
                    }
                    break;
                case 250 /* JsxSelfClosingElement */:
                    if (token.parent.tagName === token) {
                        return 21 /* jsxSelfClosingTagName */;
                    }
                    break;
                case 253 /* JsxAttribute */:
                    if (token.parent.name === token) {
                        return 22 /* jsxAttribute */;
                    }
                    break;
            }
            return undefined;
        }
        // for accurate classification, the actual token should be passed in.  however, for
        // cases like 'disabled merge code' classification, we just get the token kind and
        // classify based on that instead.
        function classifyTokenType(tokenKind, token) {
            if (ts.isKeyword(tokenKind)) {
                return 3 /* keyword */;
            }
            // Special case < and >  If they appear in a generic context they are punctuation,
            // not operators.
            if (tokenKind === 27 /* LessThanToken */ || tokenKind === 29 /* GreaterThanToken */) {
                // If the node owning the token has a type argument list or type parameter list, then
                // we can effectively assume that a '<' and '>' belong to those lists.
                if (token && ts.getTypeArgumentOrTypeParameterList(token.parent)) {
                    return 10 /* punctuation */;
                }
            }
            if (ts.isPunctuation(tokenKind)) {
                if (token) {
                    if (tokenKind === 58 /* EqualsToken */) {
                        // the '=' in a variable declaration is special cased here.
                        if (token.parent.kind === 226 /* VariableDeclaration */ ||
                            token.parent.kind === 149 /* PropertyDeclaration */ ||
                            token.parent.kind === 146 /* Parameter */ ||
                            token.parent.kind === 253 /* JsxAttribute */) {
                            return 5 /* operator */;
                        }
                    }
                    if (token.parent.kind === 194 /* BinaryExpression */ ||
                        token.parent.kind === 192 /* PrefixUnaryExpression */ ||
                        token.parent.kind === 193 /* PostfixUnaryExpression */ ||
                        token.parent.kind === 195 /* ConditionalExpression */) {
                        return 5 /* operator */;
                    }
                }
                return 10 /* punctuation */;
            }
            else if (tokenKind === 8 /* NumericLiteral */) {
                return 4 /* numericLiteral */;
            }
            else if (tokenKind === 9 /* StringLiteral */) {
                return token.parent.kind === 253 /* JsxAttribute */ ? 24 /* jsxAttributeStringLiteralValue */ : 6 /* stringLiteral */;
            }
            else if (tokenKind === 12 /* RegularExpressionLiteral */) {
                // TODO: we should get another classification type for these literals.
                return 6 /* stringLiteral */;
            }
            else if (ts.isTemplateLiteralKind(tokenKind)) {
                // TODO (drosen): we should *also* get another classification type for these literals.
                return 6 /* stringLiteral */;
            }
            else if (tokenKind === 10 /* JsxText */) {
                return 23 /* jsxText */;
            }
            else if (tokenKind === 71 /* Identifier */) {
                if (token) {
                    switch (token.parent.kind) {
                        case 229 /* ClassDeclaration */:
                            if (token.parent.name === token) {
                                return 11 /* className */;
                            }
                            return;
                        case 145 /* TypeParameter */:
                            if (token.parent.name === token) {
                                return 15 /* typeParameterName */;
                            }
                            return;
                        case 230 /* InterfaceDeclaration */:
                            if (token.parent.name === token) {
                                return 13 /* interfaceName */;
                            }
                            return;
                        case 232 /* EnumDeclaration */:
                            if (token.parent.name === token) {
                                return 12 /* enumName */;
                            }
                            return;
                        case 233 /* ModuleDeclaration */:
                            if (token.parent.name === token) {
                                return 14 /* moduleName */;
                            }
                            return;
                        case 146 /* Parameter */:
                            if (token.parent.name === token) {
                                return ts.isThisIdentifier(token) ? 3 /* keyword */ : 17 /* parameterName */;
                            }
                            return;
                    }
                }
                return 2 /* identifier */;
            }
        }
        function processElement(element) {
            if (!element) {
                return;
            }
            // Ignore nodes that don't intersect the original span to classify.
            if (ts.decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
                checkForClassificationCancellation(cancellationToken, element.kind);
                for (var _i = 0, _a = element.getChildren(sourceFile); _i < _a.length; _i++) {
                    var child = _a[_i];
                    if (!tryClassifyNode(child)) {
                        // Recurse into our child nodes.
                        processElement(child);
                    }
                }
            }
        }
    }
    ts.getEncodedSyntacticClassifications = getEncodedSyntacticClassifications;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Completions;
    (function (Completions) {
        var PathCompletions;
        (function (PathCompletions) {
            function getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker) {
                var literalValue = ts.normalizeSlashes(node.text);
                var scriptPath = node.getSourceFile().path;
                var scriptDirectory = ts.getDirectoryPath(scriptPath);
                var span = getDirectoryFragmentTextSpan(node.text, node.getStart() + 1);
                var entries;
                if (isPathRelativeToScript(literalValue) || ts.isRootedDiskPath(literalValue)) {
                    var extensions = ts.getSupportedExtensions(compilerOptions);
                    if (compilerOptions.rootDirs) {
                        entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath);
                    }
                    else {
                        entries = getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath);
                    }
                }
                else {
                    // Check for node modules
                    entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
                }
                return {
                    isGlobalCompletion: false,
                    isMemberCompletion: false,
                    isNewIdentifierLocation: true,
                    entries: entries
                };
            }
            PathCompletions.getStringLiteralCompletionEntriesFromModuleNames = getStringLiteralCompletionEntriesFromModuleNames;
            /**
             * Takes a script path and returns paths for all potential folders that could be merged with its
             * containing folder via the "rootDirs" compiler option
             */
            function getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase) {
                // Make all paths absolute/normalized if they are not already
                rootDirs = ts.map(rootDirs, function (rootDirectory) { return ts.normalizePath(ts.isRootedDiskPath(rootDirectory) ? rootDirectory : ts.combinePaths(basePath, rootDirectory)); });
                // Determine the path to the directory containing the script relative to the root directory it is contained within
                var relativeDirectory = ts.forEach(rootDirs, function (rootDirectory) {
                    return ts.containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined;
                });
                // Now find a path for each potential directory that is to be merged with the one containing the script
                return ts.deduplicate(ts.map(rootDirs, function (rootDirectory) { return ts.combinePaths(rootDirectory, relativeDirectory); }));
            }
            function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs, fragment, scriptPath, extensions, includeExtensions, span, compilerOptions, host, exclude) {
                var basePath = compilerOptions.project || host.getCurrentDirectory();
                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
                var baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase);
                var result = [];
                for (var _i = 0, baseDirectories_1 = baseDirectories; _i < baseDirectories_1.length; _i++) {
                    var baseDirectory = baseDirectories_1[_i];
                    getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, host, exclude, result);
                }
                return result;
            }
            /**
             * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
             */
            function getCompletionEntriesForDirectoryFragment(fragment, scriptPath, extensions, includeExtensions, span, host, exclude, result) {
                if (result === void 0) { result = []; }
                if (fragment === undefined) {
                    fragment = "";
                }
                fragment = ts.normalizeSlashes(fragment);
                /**
                 * Remove the basename from the path. Note that we don't use the basename to filter completions;
                 * the client is responsible for refining completions.
                 */
                fragment = ts.getDirectoryPath(fragment);
                if (fragment === "") {
                    fragment = "." + ts.directorySeparator;
                }
                fragment = ts.ensureTrailingDirectorySeparator(fragment);
                var absolutePath = normalizeAndPreserveTrailingSlash(ts.isRootedDiskPath(fragment) ? fragment : ts.combinePaths(scriptPath, fragment));
                var baseDirectory = ts.getDirectoryPath(absolutePath);
                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
                if (tryDirectoryExists(host, baseDirectory)) {
                    // Enumerate the available files if possible
                    var files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
                    if (files) {
                        /**
                         * Multiple file entries might map to the same truncated name once we remove extensions
                         * (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
                         *
                         * both foo.ts and foo.tsx become foo
                         */
                        var foundFiles = ts.createMap();
                        for (var _i = 0, files_3 = files; _i < files_3.length; _i++) {
                            var filePath = files_3[_i];
                            filePath = ts.normalizePath(filePath);
                            if (exclude && ts.comparePaths(filePath, exclude, scriptPath, ignoreCase) === 0 /* EqualTo */) {
                                continue;
                            }
                            var foundFileName = includeExtensions ? ts.getBaseFileName(filePath) : ts.removeFileExtension(ts.getBaseFileName(filePath));
                            if (!foundFiles.get(foundFileName)) {
                                foundFiles.set(foundFileName, true);
                            }
                        }
                        ts.forEachKey(foundFiles, function (foundFile) {
                            result.push(createCompletionEntryForModule(foundFile, "script" /* scriptElement */, span));
                        });
                    }
                    // If possible, get folder completion as well
                    var directories = tryGetDirectories(host, baseDirectory);
                    if (directories) {
                        for (var _a = 0, directories_2 = directories; _a < directories_2.length; _a++) {
                            var directory = directories_2[_a];
                            var directoryName = ts.getBaseFileName(ts.normalizePath(directory));
                            result.push(createCompletionEntryForModule(directoryName, "directory" /* directory */, span));
                        }
                    }
                }
                return result;
            }
            /**
             * Check all of the declared modules and those in node modules. Possible sources of modules:
             *      Modules that are found by the type checker
             *      Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
             *      Modules from node_modules (i.e. those listed in package.json)
             *          This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
             */
            function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, span, compilerOptions, host, typeChecker) {
                var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
                var result;
                if (baseUrl) {
                    var fileExtensions = ts.getSupportedExtensions(compilerOptions);
                    var projectDir = compilerOptions.project || host.getCurrentDirectory();
                    var absolute = ts.isRootedDiskPath(baseUrl) ? baseUrl : ts.combinePaths(projectDir, baseUrl);
                    result = getCompletionEntriesForDirectoryFragment(fragment, ts.normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host);
                    if (paths) {
                        for (var path in paths) {
                            if (paths.hasOwnProperty(path)) {
                                if (path === "*") {
                                    if (paths[path]) {
                                        for (var _i = 0, _a = paths[path]; _i < _a.length; _i++) {
                                            var pattern = _a[_i];
                                            for (var _b = 0, _c = getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host); _b < _c.length; _b++) {
                                                var match = _c[_b];
                                                result.push(createCompletionEntryForModule(match, "external module name" /* externalModuleName */, span));
                                            }
                                        }
                                    }
                                }
                                else if (ts.startsWith(path, fragment)) {
                                    var entry = paths[path] && paths[path].length === 1 && paths[path][0];
                                    if (entry) {
                                        result.push(createCompletionEntryForModule(path, "external module name" /* externalModuleName */, span));
                                    }
                                }
                            }
                        }
                    }
                }
                else {
                    result = [];
                }
                getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result);
                for (var _d = 0, _e = enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host); _d < _e.length; _d++) {
                    var moduleName = _e[_d];
                    result.push(createCompletionEntryForModule(moduleName, "external module name" /* externalModuleName */, span));
                }
                return result;
            }
            function getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host) {
                if (host.readDirectory) {
                    var parsed = ts.hasZeroOrOneAsteriskCharacter(pattern) ? ts.tryParsePattern(pattern) : undefined;
                    if (parsed) {
                        // The prefix has two effective parts: the directory path and the base component after the filepath that is not a
                        // full directory component. For example: directory/path/of/prefix/base*
                        var normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix);
                        var normalizedPrefixDirectory = ts.getDirectoryPath(normalizedPrefix);
                        var normalizedPrefixBase = ts.getBaseFileName(normalizedPrefix);
                        var fragmentHasPath = ts.stringContains(fragment, ts.directorySeparator);
                        // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
                        var expandedPrefixDirectory = fragmentHasPath ? ts.combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + ts.getDirectoryPath(fragment)) : normalizedPrefixDirectory;
                        var normalizedSuffix = ts.normalizePath(parsed.suffix);
                        var baseDirectory = ts.combinePaths(baseUrl, expandedPrefixDirectory);
                        var completePrefix = fragmentHasPath ? baseDirectory : ts.ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
                        // If we have a suffix, then we need to read the directory all the way down. We could create a glob
                        // that encodes the suffix, but we would have to escape the character "?" which readDirectory
                        // doesn't support. For now, this is safer but slower
                        var includeGlob = normalizedSuffix ? "**/*" : "./*";
                        var matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]);
                        if (matches) {
                            var result = [];
                            // Trim away prefix and suffix
                            for (var _i = 0, matches_1 = matches; _i < matches_1.length; _i++) {
                                var match = matches_1[_i];
                                var normalizedMatch = ts.normalizePath(match);
                                if (!ts.endsWith(normalizedMatch, normalizedSuffix) || !ts.startsWith(normalizedMatch, completePrefix)) {
                                    continue;
                                }
                                var start = completePrefix.length;
                                var length_7 = normalizedMatch.length - start - normalizedSuffix.length;
                                result.push(ts.removeFileExtension(normalizedMatch.substr(start, length_7)));
                            }
                            return result;
                        }
                    }
                }
                return undefined;
            }
            function enumeratePotentialNonRelativeModules(fragment, scriptPath, options, typeChecker, host) {
                // Check If this is a nested module
                var isNestedModule = ts.stringContains(fragment, ts.directorySeparator);
                var moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(ts.directorySeparator)) : undefined;
                // Get modules that the type checker picked up
                var ambientModules = ts.map(typeChecker.getAmbientModules(), function (sym) { return ts.stripQuotes(sym.name); });
                var nonRelativeModuleNames = ts.filter(ambientModules, function (moduleName) { return ts.startsWith(moduleName, fragment); });
                // Nested modules of the form "module-name/sub" need to be adjusted to only return the string
                // after the last '/' that appears in the fragment because that's where the replacement span
                // starts
                if (isNestedModule) {
                    var moduleNameWithSeperator_1 = ts.ensureTrailingDirectorySeparator(moduleNameFragment);
                    nonRelativeModuleNames = ts.map(nonRelativeModuleNames, function (nonRelativeModuleName) {
                        return ts.removePrefix(nonRelativeModuleName, moduleNameWithSeperator_1);
                    });
                }
                if (!options.moduleResolution || options.moduleResolution === ts.ModuleResolutionKind.NodeJs) {
                    for (var _i = 0, _a = enumerateNodeModulesVisibleToScript(host, scriptPath); _i < _a.length; _i++) {
                        var visibleModule = _a[_i];
                        if (!isNestedModule) {
                            nonRelativeModuleNames.push(visibleModule.moduleName);
                        }
                        else if (ts.startsWith(visibleModule.moduleName, moduleNameFragment)) {
                            var nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, ts.supportedTypeScriptExtensions, /*exclude*/ undefined, /*include*/ ["./*"]);
                            if (nestedFiles) {
                                for (var _b = 0, nestedFiles_1 = nestedFiles; _b < nestedFiles_1.length; _b++) {
                                    var f = nestedFiles_1[_b];
                                    f = ts.normalizePath(f);
                                    var nestedModule = ts.removeFileExtension(ts.getBaseFileName(f));
                                    nonRelativeModuleNames.push(nestedModule);
                                }
                            }
                        }
                    }
                }
                return ts.deduplicate(nonRelativeModuleNames);
            }
            function getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host) {
                var token = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
                if (!token) {
                    return undefined;
                }
                var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
                if (!commentRanges || !commentRanges.length) {
                    return undefined;
                }
                var range = ts.forEach(commentRanges, function (commentRange) { return position >= commentRange.pos && position <= commentRange.end && commentRange; });
                if (!range) {
                    return undefined;
                }
                var completionInfo = {
                    /**
                     * We don't want the editor to offer any other completions, such as snippets, inside a comment.
                     */
                    isGlobalCompletion: false,
                    isMemberCompletion: false,
                    /**
                     * The user may type in a path that doesn't yet exist, creating a "new identifier"
                     * with respect to the collection of identifiers the server is aware of.
                     */
                    isNewIdentifierLocation: true,
                    entries: []
                };
                var text = sourceFile.text.substr(range.pos, position - range.pos);
                var match = tripleSlashDirectiveFragmentRegex.exec(text);
                if (match) {
                    var prefix = match[1];
                    var kind = match[2];
                    var toComplete = match[3];
                    var scriptPath = ts.getDirectoryPath(sourceFile.path);
                    if (kind === "path") {
                        // Give completions for a relative path
                        var span_10 = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
                        completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, ts.getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span_10, host, sourceFile.path);
                    }
                    else {
                        // Give completions based on the typings available
                        var span_11 = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
                        completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span_11);
                    }
                }
                return completionInfo;
            }
            PathCompletions.getTripleSlashReferenceCompletion = getTripleSlashReferenceCompletion;
            function getCompletionEntriesFromTypings(host, options, scriptPath, span, result) {
                if (result === void 0) { result = []; }
                // Check for typings specified in compiler options
                if (options.types) {
                    for (var _i = 0, _a = options.types; _i < _a.length; _i++) {
                        var moduleName = _a[_i];
                        result.push(createCompletionEntryForModule(moduleName, "external module name" /* externalModuleName */, span));
                    }
                }
                else if (host.getDirectories) {
                    var typeRoots = void 0;
                    try {
                        // Wrap in try catch because getEffectiveTypeRoots touches the filesystem
                        typeRoots = ts.getEffectiveTypeRoots(options, host);
                    }
                    catch (e) { }
                    if (typeRoots) {
                        for (var _b = 0, typeRoots_2 = typeRoots; _b < typeRoots_2.length; _b++) {
                            var root = typeRoots_2[_b];
                            getCompletionEntriesFromDirectories(host, root, span, result);
                        }
                    }
                }
                if (host.getDirectories) {
                    // Also get all @types typings installed in visible node_modules directories
                    for (var _c = 0, _d = findPackageJsons(scriptPath, host); _c < _d.length; _c++) {
                        var packageJson = _d[_c];
                        var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
                        getCompletionEntriesFromDirectories(host, typesDir, span, result);
                    }
                }
                return result;
            }
            function getCompletionEntriesFromDirectories(host, directory, span, result) {
                if (host.getDirectories && tryDirectoryExists(host, directory)) {
                    var directories = tryGetDirectories(host, directory);
                    if (directories) {
                        for (var _i = 0, directories_3 = directories; _i < directories_3.length; _i++) {
                            var typeDirectory = directories_3[_i];
                            typeDirectory = ts.normalizePath(typeDirectory);
                            result.push(createCompletionEntryForModule(ts.getBaseFileName(typeDirectory), "external module name" /* externalModuleName */, span));
                        }
                    }
                }
            }
            function findPackageJsons(currentDir, host) {
                var paths = [];
                var currentConfigPath;
                while (true) {
                    currentConfigPath = ts.findConfigFile(currentDir, function (f) { return tryFileExists(host, f); }, "package.json");
                    if (currentConfigPath) {
                        paths.push(currentConfigPath);
                        currentDir = ts.getDirectoryPath(currentConfigPath);
                        var parent = ts.getDirectoryPath(currentDir);
                        if (currentDir === parent) {
                            break;
                        }
                        currentDir = parent;
                    }
                    else {
                        break;
                    }
                }
                return paths;
            }
            function enumerateNodeModulesVisibleToScript(host, scriptPath) {
                var result = [];
                if (host.readFile && host.fileExists) {
                    for (var _i = 0, _a = findPackageJsons(scriptPath, host); _i < _a.length; _i++) {
                        var packageJson = _a[_i];
                        var contents = tryReadingPackageJson(packageJson);
                        if (!contents) {
                            return;
                        }
                        var nodeModulesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules");
                        var foundModuleNames = [];
                        // Provide completions for all non @types dependencies
                        for (var _b = 0, nodeModulesDependencyKeys_1 = nodeModulesDependencyKeys; _b < nodeModulesDependencyKeys_1.length; _b++) {
                            var key = nodeModulesDependencyKeys_1[_b];
                            addPotentialPackageNames(contents[key], foundModuleNames);
                        }
                        for (var _c = 0, foundModuleNames_1 = foundModuleNames; _c < foundModuleNames_1.length; _c++) {
                            var moduleName = foundModuleNames_1[_c];
                            var moduleDir = ts.combinePaths(nodeModulesDir, moduleName);
                            result.push({
                                moduleName: moduleName,
                                moduleDir: moduleDir
                            });
                        }
                    }
                }
                return result;
                function tryReadingPackageJson(filePath) {
                    try {
                        var fileText = tryReadFile(host, filePath);
                        return fileText ? JSON.parse(fileText) : undefined;
                    }
                    catch (e) {
                        return undefined;
                    }
                }
                function addPotentialPackageNames(dependencies, result) {
                    if (dependencies) {
                        for (var dep in dependencies) {
                            if (dependencies.hasOwnProperty(dep) && !ts.startsWith(dep, "@types/")) {
                                result.push(dep);
                            }
                        }
                    }
                }
            }
            function createCompletionEntryForModule(name, kind, replacementSpan) {
                return { name: name, kind: kind, kindModifiers: "" /* none */, sortText: name, replacementSpan: replacementSpan };
            }
            // Replace everything after the last directory seperator that appears
            function getDirectoryFragmentTextSpan(text, textStart) {
                var index = text.lastIndexOf(ts.directorySeparator);
                var offset = index !== -1 ? index + 1 : 0;
                return { start: textStart + offset, length: text.length - offset };
            }
            // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
            function isPathRelativeToScript(path) {
                if (path && path.length >= 2 && path.charCodeAt(0) === 46 /* dot */) {
                    var slashIndex = path.length >= 3 && path.charCodeAt(1) === 46 /* dot */ ? 2 : 1;
                    var slashCharCode = path.charCodeAt(slashIndex);
                    return slashCharCode === 47 /* slash */ || slashCharCode === 92 /* backslash */;
                }
                return false;
            }
            function normalizeAndPreserveTrailingSlash(path) {
                return ts.hasTrailingDirectorySeparator(path) ? ts.ensureTrailingDirectorySeparator(ts.normalizePath(path)) : ts.normalizePath(path);
            }
            /**
             * Matches a triple slash reference directive with an incomplete string literal for its path. Used
             * to determine if the caret is currently within the string literal and capture the literal fragment
             * for completions.
             * For example, this matches
             *
             * /// <reference path="fragment
             *
             * but not
             *
             * /// <reference path="fragment"
             */
            var tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
            var nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
            function tryGetDirectories(host, directoryName) {
                return tryIOAndConsumeErrors(host, host.getDirectories, directoryName);
            }
            function tryReadDirectory(host, path, extensions, exclude, include) {
                return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include);
            }
            function tryReadFile(host, path) {
                return tryIOAndConsumeErrors(host, host.readFile, path);
            }
            function tryFileExists(host, path) {
                return tryIOAndConsumeErrors(host, host.fileExists, path);
            }
            function tryDirectoryExists(host, path) {
                try {
                    return ts.directoryProbablyExists(path, host);
                }
                catch (e) { }
                return undefined;
            }
            function tryIOAndConsumeErrors(host, toApply) {
                var args = [];
                for (var _i = 2; _i < arguments.length; _i++) {
                    args[_i - 2] = arguments[_i];
                }
                try {
                    return toApply && toApply.apply(host, args);
                }
                catch (e) { }
                return undefined;
            }
        })(PathCompletions = Completions.PathCompletions || (Completions.PathCompletions = {}));
    })(Completions = ts.Completions || (ts.Completions = {}));
})(ts || (ts = {}));
/// <reference path="./pathCompletions.ts" />
/* @internal */
var ts;
(function (ts) {
    var Completions;
    (function (Completions) {
        var KeywordCompletionFilters;
        (function (KeywordCompletionFilters) {
            KeywordCompletionFilters[KeywordCompletionFilters["None"] = 0] = "None";
            KeywordCompletionFilters[KeywordCompletionFilters["ClassElementKeywords"] = 1] = "ClassElementKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["ConstructorParameterKeywords"] = 2] = "ConstructorParameterKeywords";
        })(KeywordCompletionFilters || (KeywordCompletionFilters = {}));
        function getCompletionsAtPosition(host, typeChecker, log, compilerOptions, sourceFile, position, allSourceFiles) {
            if (ts.isInReferenceComment(sourceFile, position)) {
                return Completions.PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
            }
            if (ts.isInString(sourceFile, position)) {
                return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
            }
            var completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
            if (!completionData) {
                return undefined;
            }
            var symbols = completionData.symbols, isGlobalCompletion = completionData.isGlobalCompletion, isMemberCompletion = completionData.isMemberCompletion, allowStringLiteral = completionData.allowStringLiteral, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, request = completionData.request, keywordFilters = completionData.keywordFilters, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap;
            if (sourceFile.languageVariant === 1 /* JSX */ &&
                location && location.parent && location.parent.kind === 252 /* JsxClosingElement */) {
                // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
                // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element.
                // For example:
                //     var x = <div> </ /*1*/>  completion list at "1" will contain "div" with type any
                var tagName = location.parent.parent.openingElement.tagName;
                return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false,
                    entries: [{
                            name: tagName.getFullText(),
                            kind: "class" /* classElement */,
                            kindModifiers: undefined,
                            sortText: "0",
                        }] };
            }
            if (request) {
                var entries_2 = request.kind === "JsDocTagName"
                    // If the current position is a jsDoc tag name, only tag names should be provided for completion
                    ? ts.JsDoc.getJSDocTagNameCompletions()
                    : request.kind === "JsDocTag"
                        // If the current position is a jsDoc tag, only tags should be provided for completion
                        ? ts.JsDoc.getJSDocTagCompletions()
                        : ts.JsDoc.getJSDocParameterNameCompletions(request.tag);
                return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries_2 };
            }
            var entries = [];
            if (ts.isSourceFileJavaScript(sourceFile)) {
                var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, symbolToOriginInfoMap);
                getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries);
            }
            else {
                if ((!symbols || symbols.length === 0) && keywordFilters === 0 /* None */) {
                    return undefined;
                }
                getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, symbolToOriginInfoMap);
            }
            // TODO add filter for keyword based on type/value/namespace and also location
            // Add all keywords if
            // - this is not a member completion list (all the keywords)
            // - other filters are enabled in required scenario so add those keywords
            if (keywordFilters !== 0 /* None */ || !isMemberCompletion) {
                ts.addRange(entries, getKeywordCompletions(keywordFilters));
            }
            return { isGlobalCompletion: isGlobalCompletion, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
        }
        Completions.getCompletionsAtPosition = getCompletionsAtPosition;
        function getJavaScriptCompletionEntries(sourceFile, position, uniqueNames, target, entries) {
            ts.getNameTable(sourceFile).forEach(function (pos, name) {
                // Skip identifiers produced only from the current location
                if (pos === position) {
                    return;
                }
                var realName = ts.unescapeLeadingUnderscores(name);
                if (uniqueNames.has(realName)) {
                    return;
                }
                uniqueNames.set(realName, true);
                var displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true, /*allowStringLiteral*/ false);
                if (displayName) {
                    entries.push({
                        name: displayName,
                        kind: "warning" /* warning */,
                        kindModifiers: "",
                        sortText: "1"
                    });
                }
            });
        }
        function createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin) {
            // Try to get a valid display name for this symbol, if we could not find one, then ignore it.
            // We would like to only show things that can be added after a dot, so for instance numeric properties can
            // not be accessed with a dot (a.1 <- invalid)
            var displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral);
            if (!displayName) {
                return undefined;
            }
            // TODO(drosen): Right now we just permit *all* semantic meanings when calling
            // 'getSymbolKind' which is permissible given that it is backwards compatible; but
            // really we should consider passing the meaning for the node so that we don't report
            // that a suggestion for a value is an interface.  We COULD also just do what
            // 'getSymbolModifiers' does, which is to use the first declaration.
            // Use a 'sortText' of 0' so that all symbol completion entries come before any other
            // entries (like JavaScript identifier entries).
            return {
                name: displayName,
                kind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, location),
                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
                sortText: "0",
                source: getSourceFromOrigin(origin),
                hasAction: origin === undefined ? undefined : true,
            };
        }
        function getSourceFromOrigin(origin) {
            return origin && ts.stripQuotes(origin.moduleSymbol.name);
        }
        function getCompletionEntriesFromSymbols(symbols, entries, location, performCharacterChecks, typeChecker, target, log, allowStringLiteral, symbolToOriginInfoMap) {
            var start = ts.timestamp();
            // Tracks unique names.
            // We don't set this for global variables or completions from external module exports, because we can have multiple of those.
            // Based on the order we add things we will always see locals first, then globals, then module exports.
            // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
            var uniques = ts.createMap();
            if (symbols) {
                for (var _i = 0, symbols_5 = symbols; _i < symbols_5.length; _i++) {
                    var symbol = symbols_5[_i];
                    var origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[ts.getSymbolId(symbol)] : undefined;
                    var entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin);
                    if (!entry) {
                        continue;
                    }
                    var name = entry.name;
                    if (uniques.has(name)) {
                        continue;
                    }
                    // Latter case tests whether this is a global variable.
                    if (!origin && !(symbol.parent === undefined && !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === location.getSourceFile(); }))) {
                        uniques.set(name, true);
                    }
                    entries.push(entry);
                }
            }
            log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (ts.timestamp() - start));
            return uniques;
        }
        function getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log) {
            var node = ts.findPrecedingToken(position, sourceFile);
            if (!node || node.kind !== 9 /* StringLiteral */) {
                return undefined;
            }
            if (node.parent.kind === 261 /* PropertyAssignment */ &&
                node.parent.parent.kind === 178 /* ObjectLiteralExpression */ &&
                node.parent.name === node) {
                // Get quoted name of properties of the object literal expression
                // i.e. interface ConfigFiles {
                //          'jspm:dev': string
                //      }
                //      let files: ConfigFiles = {
                //          '/*completion position*/'
                //      }
                //
                //      function foo(c: ConfigFiles) {}
                //      foo({
                //          '/*completion position*/'
                //      });
                return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, typeChecker, compilerOptions.target, log);
            }
            else if (ts.isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) {
                // Get all names of properties on the expression
                // i.e. interface A {
                //      'prop1': string
                // }
                // let a: A;
                // a['/*completion position*/']
                return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
            }
            else if (node.parent.kind === 238 /* ImportDeclaration */ || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node) || ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
                // Get all known external module names or complete a path to a module
                // i.e. import * as ns from "/*completion position*/";
                //      import x = require("/*completion position*/");
                //      var y = require("/*completion position*/");
                return Completions.PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker);
            }
            else if (isEqualityExpression(node.parent)) {
                // Get completions from the type of the other operand
                // i.e. switch (a) {
                //         case '/*completion position*/'
                //      }
                return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
            }
            else if (ts.isCaseOrDefaultClause(node.parent)) {
                // Get completions from the type of the switch expression
                // i.e. x === '/*completion position'
                return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.parent.parent.expression), typeChecker);
            }
            else {
                var argumentInfo = ts.SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
                if (argumentInfo) {
                    // Get string literal completions from specialized signatures of the target
                    // i.e. declare function f(a: 'A');
                    // f("/*completion position*/")
                    return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker);
                }
                // Get completion for string literal from string literal type
                // i.e. var x: "hi" | "hello" = "/*completion position*/"
                return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker);
            }
        }
        function getStringLiteralCompletionEntriesFromPropertyAssignment(element, typeChecker, target, log) {
            var type = typeChecker.getContextualType(element.parent);
            var entries = [];
            if (type) {
                getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
                if (entries.length) {
                    return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries };
                }
            }
        }
        function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker) {
            var candidates = [];
            var entries = [];
            var uniques = ts.createMap();
            typeChecker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
            for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
                var candidate = candidates_1[_i];
                addStringLiteralCompletionsFromType(typeChecker.getParameterType(candidate, argumentInfo.argumentIndex), entries, typeChecker, uniques);
            }
            if (entries.length) {
                return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: true, entries: entries };
            }
            return undefined;
        }
        function getStringLiteralCompletionEntriesFromElementAccess(node, typeChecker, target, log) {
            var type = typeChecker.getTypeAtLocation(node.expression);
            var entries = [];
            if (type) {
                getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
                if (entries.length) {
                    return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries };
                }
            }
            return undefined;
        }
        function getStringLiteralCompletionEntriesFromType(type, typeChecker) {
            if (type) {
                var entries = [];
                addStringLiteralCompletionsFromType(type, entries, typeChecker);
                if (entries.length) {
                    return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries };
                }
            }
            return undefined;
        }
        function addStringLiteralCompletionsFromType(type, result, typeChecker, uniques) {
            if (uniques === void 0) { uniques = ts.createMap(); }
            if (type && type.flags & 16384 /* TypeParameter */) {
                type = typeChecker.getBaseConstraintOfType(type);
            }
            if (!type) {
                return;
            }
            if (type.flags & 65536 /* Union */) {
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    addStringLiteralCompletionsFromType(t, result, typeChecker, uniques);
                }
            }
            else if (type.flags & 32 /* StringLiteral */ && !(type.flags & 256 /* EnumLiteral */)) {
                var name = type.value;
                if (!uniques.has(name)) {
                    uniques.set(name, true);
                    result.push({
                        name: name,
                        kindModifiers: "" /* none */,
                        kind: "var" /* variableElement */,
                        sortText: "0"
                    });
                }
            }
        }
        function getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, _a, allSourceFiles) {
            var name = _a.name, source = _a.source;
            var completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
            if (!completionData) {
                return undefined;
            }
            var symbols = completionData.symbols, location = completionData.location, allowStringLiteral = completionData.allowStringLiteral, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap;
            // Find the symbol with the matching entry name.
            // We don't need to perform character checks here because we're only comparing the
            // name against 'entryName' (which is known to be good), not building a new
            // completion entry.
            var symbol = ts.find(symbols, function (s) {
                return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name
                    && getSourceFromOrigin(symbolToOriginInfoMap[ts.getSymbolId(s)]) === source;
            });
            return symbol && { symbol: symbol, location: location, symbolToOriginInfoMap: symbolToOriginInfoMap };
        }
        function getCompletionEntryDetails(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles, host, rulesProvider) {
            var name = entryId.name, source = entryId.source;
            // Compute all the completion symbols again.
            var symbolCompletion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
            if (symbolCompletion) {
                var symbol = symbolCompletion.symbol, location = symbolCompletion.location, symbolToOriginInfoMap = symbolCompletion.symbolToOriginInfoMap;
                var codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, rulesProvider);
                var kindModifiers = ts.SymbolDisplay.getSymbolModifiers(symbol);
                var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, 7 /* All */), displayParts = _a.displayParts, documentation = _a.documentation, symbolKind = _a.symbolKind, tags = _a.tags;
                return { name: name, kindModifiers: kindModifiers, kind: symbolKind, displayParts: displayParts, documentation: documentation, tags: tags, codeActions: codeActions, source: source === undefined ? undefined : [ts.textPart(source)] };
            }
            // Didn't find a symbol with this name.  See if we can find a keyword instead.
            if (source === undefined && ts.some(getKeywordCompletions(0 /* None */), function (c) { return c.name === name; })) {
                return {
                    name: name,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "" /* none */,
                    displayParts: [ts.displayPart(name, ts.SymbolDisplayPartKind.keyword)],
                    documentation: undefined,
                    tags: undefined,
                    codeActions: undefined,
                    source: undefined,
                };
            }
            return undefined;
        }
        Completions.getCompletionEntryDetails = getCompletionEntryDetails;
        function getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, checker, host, compilerOptions, sourceFile, rulesProvider) {
            var symbolOriginInfo = symbolToOriginInfoMap[ts.getSymbolId(symbol)];
            if (!symbolOriginInfo) {
                return undefined;
            }
            var moduleSymbol = symbolOriginInfo.moduleSymbol, isDefaultExport = symbolOriginInfo.isDefaultExport;
            return ts.codefix.getCodeActionForImport(moduleSymbol, {
                host: host,
                checker: checker,
                newLineCharacter: host.getNewLine(),
                compilerOptions: compilerOptions,
                sourceFile: sourceFile,
                rulesProvider: rulesProvider,
                symbolName: symbol.name,
                getCanonicalFileName: ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false),
                symbolToken: undefined,
                kind: isDefaultExport ? 1 /* Default */ : 0 /* Named */,
            });
        }
        function getCompletionEntrySymbol(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles) {
            var completion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
            return completion && completion.symbol;
        }
        Completions.getCompletionEntrySymbol = getCompletionEntrySymbol;
        function getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles) {
            var isJavaScriptFile = ts.isSourceFileJavaScript(sourceFile);
            var request;
            var start = ts.timestamp();
            var currentToken = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853
            // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.)
            log("getCompletionData: Get current token: " + (ts.timestamp() - start));
            start = ts.timestamp();
            // Completion not allowed inside comments, bail out if this is the case
            var insideComment = ts.isInComment(sourceFile, position, currentToken);
            log("getCompletionData: Is inside comment: " + (ts.timestamp() - start));
            var insideJsDocTagTypeExpression = false;
            if (insideComment) {
                if (ts.hasDocComment(sourceFile, position)) {
                    if (sourceFile.text.charCodeAt(position - 1) === 64 /* at */) {
                        // The current position is next to the '@' sign, when no tag name being provided yet.
                        // Provide a full list of tag names
                        request = { kind: "JsDocTagName" };
                    }
                    else {
                        // When completion is requested without "@", we will have check to make sure that
                        // there are no comments prefix the request position. We will only allow "*" and space.
                        // e.g
                        //   /** |c| /*
                        //
                        //   /**
                        //     |c|
                        //    */
                        //
                        //   /**
                        //    * |c|
                        //    */
                        //
                        //   /**
                        //    *         |c|
                        //    */
                        var lineStart = ts.getLineStartPositionForPosition(position, sourceFile);
                        if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) {
                            request = { kind: "JsDocTag" };
                        }
                    }
                }
                // Completion should work inside certain JsDoc tags. For example:
                //     /** @type {number | string} */
                // Completion should work in the brackets
                var tag = getJsDocTagAtPosition(currentToken, position);
                if (tag) {
                    if (tag.tagName.pos <= position && position <= tag.tagName.end) {
                        request = { kind: "JsDocTagName" };
                    }
                    if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === 267 /* JSDocTypeExpression */) {
                        currentToken = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true);
                        if (!currentToken ||
                            (!ts.isDeclarationName(currentToken) &&
                                (currentToken.parent.kind !== 284 /* JSDocPropertyTag */ ||
                                    currentToken.parent.name !== currentToken))) {
                            // Use as type location if inside tag's type expression
                            insideJsDocTagTypeExpression = isCurrentlyEditingNode(tag.typeExpression);
                        }
                    }
                    if (ts.isJSDocParameterTag(tag) && (ts.nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) {
                        request = { kind: "JsDocParameterName", tag: tag };
                    }
                }
                if (request) {
                    return {
                        symbols: undefined,
                        isGlobalCompletion: false,
                        isMemberCompletion: false,
                        allowStringLiteral: false,
                        isNewIdentifierLocation: false,
                        location: undefined,
                        isRightOfDot: false,
                        request: request,
                        keywordFilters: 0 /* None */,
                        symbolToOriginInfoMap: undefined,
                    };
                }
                if (!insideJsDocTagTypeExpression) {
                    // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
                    // comment or the plain text part of a jsDoc comment, so no completion should be available
                    log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment.");
                    return undefined;
                }
            }
            start = ts.timestamp();
            var previousToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression);
            log("getCompletionData: Get previous token 1: " + (ts.timestamp() - start));
            // The decision to provide completion depends on the contextToken, which is determined through the previousToken.
            // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file
            var contextToken = previousToken;
            // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
            // Skip this partial identifier and adjust the contextToken to the token that precedes it.
            if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) {
                var start_4 = ts.timestamp();
                contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression);
                log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_4));
            }
            // Find the node where completion is requested on.
            // Also determine whether we are trying to complete with members of that node
            // or attributes of a JSX tag.
            var node = currentToken;
            var isRightOfDot = false;
            var isRightOfOpenTag = false;
            var isStartingCloseTag = false;
            var location = ts.getTouchingPropertyName(sourceFile, position, insideJsDocTagTypeExpression); // TODO: GH#15853
            if (contextToken) {
                // Bail out if this is a known invalid completion location
                if (isCompletionListBlocker(contextToken)) {
                    log("Returning an empty list because completion was requested in an invalid position.");
                    return undefined;
                }
                var parent = contextToken.parent;
                if (contextToken.kind === 23 /* DotToken */) {
                    if (parent.kind === 179 /* PropertyAccessExpression */) {
                        node = contextToken.parent.expression;
                        isRightOfDot = true;
                    }
                    else if (parent.kind === 143 /* QualifiedName */) {
                        node = contextToken.parent.left;
                        isRightOfDot = true;
                    }
                    else {
                        // There is nothing that precedes the dot, so this likely just a stray character
                        // or leading into a '...' token. Just bail out instead.
                        return undefined;
                    }
                }
                else if (sourceFile.languageVariant === 1 /* JSX */) {
                    // <UI.Test /* completion position */ />
                    // If the tagname is a property access expression, we will then walk up to the top most of property access expression.
                    // Then, try to get a JSX container and its associated attributes type.
                    if (parent && parent.kind === 179 /* PropertyAccessExpression */) {
                        contextToken = parent;
                        parent = parent.parent;
                    }
                    switch (parent.kind) {
                        case 252 /* JsxClosingElement */:
                            if (contextToken.kind === 41 /* SlashToken */) {
                                isStartingCloseTag = true;
                                location = contextToken;
                            }
                            break;
                        case 194 /* BinaryExpression */:
                            if (!(parent.left.flags & 32768 /* ThisNodeHasError */)) {
                                // It has a left-hand side, so we're not in an opening JSX tag.
                                break;
                            }
                        // falls through
                        case 250 /* JsxSelfClosingElement */:
                        case 249 /* JsxElement */:
                        case 251 /* JsxOpeningElement */:
                            if (contextToken.kind === 27 /* LessThanToken */) {
                                isRightOfOpenTag = true;
                                location = contextToken;
                            }
                            break;
                    }
                }
            }
            var semanticStart = ts.timestamp();
            var isGlobalCompletion = false;
            var isMemberCompletion;
            var allowStringLiteral = false;
            var isNewIdentifierLocation;
            var keywordFilters = 0 /* None */;
            var symbols = [];
            var symbolToOriginInfoMap = [];
            if (isRightOfDot) {
                getTypeScriptMemberSymbols();
            }
            else if (isRightOfOpenTag) {
                var tagSymbols = typeChecker.getJsxIntrinsicTagNames();
                if (tryGetGlobalSymbols()) {
                    symbols = tagSymbols.concat(symbols.filter(function (s) { return !!(s.flags & (107455 /* Value */ | 2097152 /* Alias */)); }));
                }
                else {
                    symbols = tagSymbols;
                }
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
            }
            else if (isStartingCloseTag) {
                var tagName = contextToken.parent.parent.openingElement.tagName;
                var tagSymbol = typeChecker.getSymbolAtLocation(tagName);
                if (!typeChecker.isUnknownSymbol(tagSymbol)) {
                    symbols = [tagSymbol];
                }
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
            }
            else {
                // For JavaScript or TypeScript, if we're not after a dot, then just try to get the
                // global symbols in scope.  These results should be valid for either language as
                // the set of symbols that can be referenced from this location.
                if (!tryGetGlobalSymbols()) {
                    return undefined;
                }
            }
            log("getCompletionData: Semantic work: " + (ts.timestamp() - semanticStart));
            return { symbols: symbols, isGlobalCompletion: isGlobalCompletion, isMemberCompletion: isMemberCompletion, allowStringLiteral: allowStringLiteral, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request: request, keywordFilters: keywordFilters, symbolToOriginInfoMap: symbolToOriginInfoMap };
            function isTagWithTypeExpression(tag) {
                switch (tag.kind) {
                    case 279 /* JSDocParameterTag */:
                    case 284 /* JSDocPropertyTag */:
                    case 280 /* JSDocReturnTag */:
                    case 281 /* JSDocTypeTag */:
                    case 283 /* JSDocTypedefTag */:
                        return true;
                }
            }
            function getTypeScriptMemberSymbols() {
                // Right of dot member completion list
                isGlobalCompletion = false;
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
                // Since this is qualified name check its a type node location
                var isTypeLocation = insideJsDocTagTypeExpression || ts.isPartOfTypeNode(node.parent);
                var isRhsOfImportDeclaration = ts.isInRightSideOfInternalImportEqualsDeclaration(node);
                if (ts.isEntityName(node)) {
                    var symbol = typeChecker.getSymbolAtLocation(node);
                    if (symbol) {
                        symbol = ts.skipAlias(symbol, typeChecker);
                        if (symbol.flags & (1536 /* Module */ | 384 /* Enum */)) {
                            // Extract module or enum members
                            var exportedSymbols = typeChecker.getExportsOfModule(symbol);
                            var isValidValueAccess_1 = function (symbol) { return typeChecker.isValidPropertyAccess((node.parent), symbol.name); };
                            var isValidTypeAccess_1 = function (symbol) { return symbolCanBeReferencedAtTypeLocation(symbol); };
                            var isValidAccess = isRhsOfImportDeclaration ?
                                // Any kind is allowed when dotting off namespace in internal import equals declaration
                                function (symbol) { return isValidTypeAccess_1(symbol) || isValidValueAccess_1(symbol); } :
                                isTypeLocation ? isValidTypeAccess_1 : isValidValueAccess_1;
                            for (var _i = 0, exportedSymbols_1 = exportedSymbols; _i < exportedSymbols_1.length; _i++) {
                                var symbol_2 = exportedSymbols_1[_i];
                                if (isValidAccess(symbol_2)) {
                                    symbols.push(symbol_2);
                                }
                            }
                            // If the module is merged with a value, we must get the type of the class and add its propertes (for inherited static methods).
                            if (!isTypeLocation && symbol.declarations.some(function (d) { return d.kind !== 265 /* SourceFile */ && d.kind !== 233 /* ModuleDeclaration */ && d.kind !== 232 /* EnumDeclaration */; })) {
                                addTypeProperties(typeChecker.getTypeOfSymbolAtLocation(symbol, node));
                            }
                            return;
                        }
                    }
                }
                if (!isTypeLocation) {
                    addTypeProperties(typeChecker.getTypeAtLocation(node));
                }
            }
            function addTypeProperties(type) {
                // Filter private properties
                for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) {
                    var symbol = _a[_i];
                    if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) {
                        symbols.push(symbol);
                    }
                }
                if (isJavaScriptFile && type.flags & 65536 /* Union */) {
                    // In javascript files, for union types, we don't just get the members that
                    // the individual types have in common, we also include all the members that
                    // each individual type has.  This is because we're going to add all identifiers
                    // anyways.  So we might as well elevate the members that were at least part
                    // of the individual types to a higher status since we know what they are.
                    var unionType = type;
                    for (var _b = 0, _c = unionType.types; _b < _c.length; _b++) {
                        var elementType = _c[_b];
                        addTypeProperties(elementType);
                    }
                }
            }
            function tryGetGlobalSymbols() {
                var objectLikeContainer;
                var namedImportsOrExports;
                var classLikeContainer;
                var jsxContainer;
                if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
                    return tryGetObjectLikeCompletionSymbols(objectLikeContainer);
                }
                if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) {
                    // cursor is in an import clause
                    // try to show exported member for imported module
                    return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
                }
                if (tryGetConstructorLikeCompletionContainer(contextToken)) {
                    // no members, only keywords
                    isMemberCompletion = false;
                    // Declaring new property/method/accessor
                    isNewIdentifierLocation = true;
                    // Has keywords for constructor parameter
                    keywordFilters = 2 /* ConstructorParameterKeywords */;
                    return true;
                }
                if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
                    // cursor inside class declaration
                    getGetClassLikeCompletionSymbols(classLikeContainer);
                    return true;
                }
                if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
                    var attrsType = void 0;
                    if ((jsxContainer.kind === 250 /* JsxSelfClosingElement */) || (jsxContainer.kind === 251 /* JsxOpeningElement */)) {
                        // Cursor is inside a JSX self-closing element or opening element
                        attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
                        if (attrsType) {
                            symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
                            isMemberCompletion = true;
                            isNewIdentifierLocation = false;
                            return true;
                        }
                    }
                }
                // Get all entities in the current scope.
                isMemberCompletion = false;
                isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken);
                if (previousToken !== contextToken) {
                    ts.Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'.");
                }
                // We need to find the node that will give us an appropriate scope to begin
                // aggregating completion candidates. This is achieved in 'getScopeNode'
                // by finding the first node that encompasses a position, accounting for whether a node
                // is "complete" to decide whether a position belongs to the node.
                //
                // However, at the end of an identifier, we are interested in the scope of the identifier
                // itself, but fall outside of the identifier. For instance:
                //
                //      xyz => x$
                //
                // the cursor is outside of both the 'x' and the arrow function 'xyz => x',
                // so 'xyz' is not returned in our results.
                //
                // We define 'adjustedPosition' so that we may appropriately account for
                // being at the end of an identifier. The intention is that if requesting completion
                // at the end of an identifier, it should be effectively equivalent to requesting completion
                // anywhere inside/at the beginning of the identifier. So in the previous case, the
                // 'adjustedPosition' will work as if requesting completion in the following:
                //
                //      xyz => $x
                //
                // If previousToken !== contextToken, then
                //   - 'contextToken' was adjusted to the token prior to 'previousToken'
                //      because we were at the end of an identifier.
                //   - 'previousToken' is defined.
                var adjustedPosition = previousToken !== contextToken ?
                    previousToken.getStart() :
                    position;
                var scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
                if (scopeNode) {
                    isGlobalCompletion =
                        scopeNode.kind === 265 /* SourceFile */ ||
                            scopeNode.kind === 196 /* TemplateExpression */ ||
                            scopeNode.kind === 256 /* JsxExpression */ ||
                            ts.isStatement(scopeNode);
                }
                var symbolMeanings = 793064 /* Type */ | 107455 /* Value */ | 1920 /* Namespace */ | 2097152 /* Alias */;
                symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
                getSymbolsFromOtherSourceFileExports(symbols, previousToken && ts.isIdentifier(previousToken) ? previousToken.text : "");
                filterGlobalCompletion(symbols);
                return true;
            }
            function filterGlobalCompletion(symbols) {
                ts.filterMutate(symbols, function (symbol) {
                    if (!ts.isSourceFile(location)) {
                        // export = /**/ here we want to get all meanings, so any symbol is ok
                        if (ts.isExportAssignment(location.parent)) {
                            return true;
                        }
                        // This is an alias, follow what it aliases
                        if (symbol && symbol.flags & 2097152 /* Alias */) {
                            symbol = typeChecker.getAliasedSymbol(symbol);
                        }
                        // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
                        if (ts.isInRightSideOfInternalImportEqualsDeclaration(location)) {
                            return !!(symbol.flags & 1920 /* Namespace */);
                        }
                        if (insideJsDocTagTypeExpression ||
                            (!isContextTokenValueLocation(contextToken) &&
                                (ts.isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)))) {
                            // Its a type, but you can reach it by namespace.type as well
                            return symbolCanBeReferencedAtTypeLocation(symbol);
                        }
                    }
                    // expressions are value space (which includes the value namespaces)
                    return !!(ts.getCombinedLocalAndExportSymbolFlags(symbol) & 107455 /* Value */);
                });
            }
            function isContextTokenValueLocation(contextToken) {
                return contextToken &&
                    contextToken.kind === 103 /* TypeOfKeyword */ &&
                    contextToken.parent.kind === 162 /* TypeQuery */;
            }
            function isContextTokenTypeLocation(contextToken) {
                if (contextToken) {
                    var parentKind = contextToken.parent.kind;
                    switch (contextToken.kind) {
                        case 56 /* ColonToken */:
                            return parentKind === 149 /* PropertyDeclaration */ ||
                                parentKind === 148 /* PropertySignature */ ||
                                parentKind === 146 /* Parameter */ ||
                                parentKind === 226 /* VariableDeclaration */ ||
                                ts.isFunctionLikeKind(parentKind);
                        case 58 /* EqualsToken */:
                            return parentKind === 231 /* TypeAliasDeclaration */;
                        case 118 /* AsKeyword */:
                            return parentKind === 202 /* AsExpression */;
                    }
                }
            }
            function symbolCanBeReferencedAtTypeLocation(symbol) {
                symbol = symbol.exportSymbol || symbol;
                // This is an alias, follow what it aliases
                symbol = ts.skipAlias(symbol, typeChecker);
                if (symbol.flags & 793064 /* Type */) {
                    return true;
                }
                if (symbol.flags & 1536 /* Module */) {
                    var exportedSymbols = typeChecker.getExportsOfModule(symbol);
                    // If the exported symbols contains type,
                    // symbol can be referenced at locations where type is allowed
                    return ts.forEach(exportedSymbols, symbolCanBeReferencedAtTypeLocation);
                }
            }
            function getSymbolsFromOtherSourceFileExports(symbols, tokenText) {
                var tokenTextLowerCase = tokenText.toLowerCase();
                ts.codefix.forEachExternalModule(typeChecker, allSourceFiles, function (moduleSymbol) {
                    if (moduleSymbol === sourceFile.symbol) {
                        return;
                    }
                    for (var _i = 0, _a = typeChecker.getExportsOfModule(moduleSymbol); _i < _a.length; _i++) {
                        var symbol = _a[_i];
                        var name = symbol.name;
                        var isDefaultExport = name === "default";
                        if (isDefaultExport) {
                            var localSymbol = ts.getLocalSymbolForExportDefault(symbol);
                            if (localSymbol) {
                                symbol = localSymbol;
                                name = localSymbol.name;
                            }
                        }
                        if (symbol.declarations && symbol.declarations.some(function (d) { return ts.isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier; })) {
                            // Don't add a completion for a re-export, only for the original.
                            continue;
                        }
                        if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) {
                            symbols.push(symbol);
                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { moduleSymbol: moduleSymbol, isDefaultExport: isDefaultExport };
                        }
                    }
                });
            }
            /**
             * True if you could remove some characters in `a` to get `b`.
             * E.g., true for "abcdef" and "bdf".
             * But not true for "abcdef" and "dbf".
             */
            function stringContainsCharactersInOrder(str, characters) {
                if (characters.length === 0) {
                    return true;
                }
                var characterIndex = 0;
                for (var strIndex = 0; strIndex < str.length; strIndex++) {
                    if (str.charCodeAt(strIndex) === characters.charCodeAt(characterIndex)) {
                        characterIndex++;
                        if (characterIndex === characters.length) {
                            return true;
                        }
                    }
                }
                // Did not find all characters
                return false;
            }
            /**
             * Finds the first node that "embraces" the position, so that one may
             * accurately aggregate locals from the closest containing scope.
             */
            function getScopeNode(initialToken, position, sourceFile) {
                var scope = initialToken;
                while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) {
                    scope = scope.parent;
                }
                return scope;
            }
            function isCompletionListBlocker(contextToken) {
                var start = ts.timestamp();
                var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) ||
                    isSolelyIdentifierDefinitionLocation(contextToken) ||
                    isDotOfNumericLiteral(contextToken) ||
                    isInJsxText(contextToken);
                log("getCompletionsAtPosition: isCompletionListBlocker: " + (ts.timestamp() - start));
                return result;
            }
            function isInJsxText(contextToken) {
                if (contextToken.kind === 10 /* JsxText */) {
                    return true;
                }
                if (contextToken.kind === 29 /* GreaterThanToken */ && contextToken.parent) {
                    if (contextToken.parent.kind === 251 /* JsxOpeningElement */) {
                        return true;
                    }
                    if (contextToken.parent.kind === 252 /* JsxClosingElement */ || contextToken.parent.kind === 250 /* JsxSelfClosingElement */) {
                        return contextToken.parent.parent && contextToken.parent.parent.kind === 249 /* JsxElement */;
                    }
                }
                return false;
            }
            function isNewIdentifierDefinitionLocation(previousToken) {
                if (previousToken) {
                    var containingNodeKind = previousToken.parent.kind;
                    switch (previousToken.kind) {
                        case 26 /* CommaToken */:
                            return containingNodeKind === 181 /* CallExpression */ // func( a, |
                                || containingNodeKind === 152 /* Constructor */ // constructor( a, |   /* public, protected, private keywords are allowed here, so show completion */
                                || containingNodeKind === 182 /* NewExpression */ // new C(a, |
                                || containingNodeKind === 177 /* ArrayLiteralExpression */ // [a, |
                                || containingNodeKind === 194 /* BinaryExpression */ // const x = (a, |
                                || containingNodeKind === 160 /* FunctionType */; // var x: (s: string, list|
                        case 19 /* OpenParenToken */:
                            return containingNodeKind === 181 /* CallExpression */ // func( |
                                || containingNodeKind === 152 /* Constructor */ // constructor( |
                                || containingNodeKind === 182 /* NewExpression */ // new C(a|
                                || containingNodeKind === 185 /* ParenthesizedExpression */ // const x = (a|
                                || containingNodeKind === 168 /* ParenthesizedType */; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */
                        case 21 /* OpenBracketToken */:
                            return containingNodeKind === 177 /* ArrayLiteralExpression */ // [ |
                                || containingNodeKind === 157 /* IndexSignature */ // [ | : string ]
                                || containingNodeKind === 144 /* ComputedPropertyName */; // [ |    /* this can become an index signature */
                        case 128 /* ModuleKeyword */: // module |
                        case 129 /* NamespaceKeyword */:// namespace |
                            return true;
                        case 23 /* DotToken */:
                            return containingNodeKind === 233 /* ModuleDeclaration */; // module A.|
                        case 17 /* OpenBraceToken */:
                            return containingNodeKind === 229 /* ClassDeclaration */; // class A{ |
                        case 58 /* EqualsToken */:
                            return containingNodeKind === 226 /* VariableDeclaration */ // const x = a|
                                || containingNodeKind === 194 /* BinaryExpression */; // x = a|
                        case 14 /* TemplateHead */:
                            return containingNodeKind === 196 /* TemplateExpression */; // `aa ${|
                        case 15 /* TemplateMiddle */:
                            return containingNodeKind === 205 /* TemplateSpan */; // `aa ${10} dd ${|
                        case 114 /* PublicKeyword */:
                        case 112 /* PrivateKeyword */:
                        case 113 /* ProtectedKeyword */:
                            return containingNodeKind === 149 /* PropertyDeclaration */; // class A{ public |
                    }
                    // Previous token may have been a keyword that was converted to an identifier.
                    switch (previousToken.getText()) {
                        case "public":
                        case "protected":
                        case "private":
                            return true;
                    }
                }
                return false;
            }
            function isInStringOrRegularExpressionOrTemplateLiteral(contextToken) {
                if (contextToken.kind === 9 /* StringLiteral */
                    || contextToken.kind === 12 /* RegularExpressionLiteral */
                    || ts.isTemplateLiteralKind(contextToken.kind)) {
                    var start_5 = contextToken.getStart();
                    var end = contextToken.getEnd();
                    // To be "in" one of these literals, the position has to be:
                    //   1. entirely within the token text.
                    //   2. at the end position of an unterminated token.
                    //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
                    if (start_5 < position && position < end) {
                        return true;
                    }
                    if (position === end) {
                        return !!contextToken.isUnterminated
                            || contextToken.kind === 12 /* RegularExpressionLiteral */;
                    }
                }
                return false;
            }
            /**
             * Aggregates relevant symbols for completion in object literals and object binding patterns.
             * Relevant symbols are stored in the captured 'symbols' variable.
             *
             * @returns true if 'symbols' was successfully populated; false otherwise.
             */
            function tryGetObjectLikeCompletionSymbols(objectLikeContainer) {
                // We're looking up possible property names from contextual/inferred/declared type.
                isMemberCompletion = true;
                allowStringLiteral = true;
                var typeMembers;
                var existingMembers;
                if (objectLikeContainer.kind === 178 /* ObjectLiteralExpression */) {
                    // We are completing on contextual types, but may also include properties
                    // other than those within the declared type.
                    isNewIdentifierLocation = true;
                    var typeForObject = typeChecker.getContextualType(objectLikeContainer);
                    if (!typeForObject)
                        return false;
                    typeMembers = getPropertiesForCompletion(typeForObject, typeChecker);
                    existingMembers = objectLikeContainer.properties;
                }
                else {
                    ts.Debug.assert(objectLikeContainer.kind === 174 /* ObjectBindingPattern */);
                    // We are *only* completing on properties from the type being destructured.
                    isNewIdentifierLocation = false;
                    var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent);
                    if (!ts.isVariableLike(rootDeclaration))
                        throw ts.Debug.fail("Root declaration is not variable-like.");
                    // We don't want to complete using the type acquired by the shape
                    // of the binding pattern; we are only interested in types acquired
                    // through type declaration or inference.
                    // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
                    // type of parameter will flow in from the contextual type of the function
                    var canGetType = rootDeclaration.initializer || rootDeclaration.type || rootDeclaration.parent.parent.kind === 216 /* ForOfStatement */;
                    if (!canGetType && rootDeclaration.kind === 146 /* Parameter */) {
                        if (ts.isExpression(rootDeclaration.parent)) {
                            canGetType = !!typeChecker.getContextualType(rootDeclaration.parent);
                        }
                        else if (rootDeclaration.parent.kind === 151 /* MethodDeclaration */ || rootDeclaration.parent.kind === 154 /* SetAccessor */) {
                            canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent);
                        }
                    }
                    if (canGetType) {
                        var typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
                        if (!typeForObject)
                            return false;
                        // In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
                        typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */); });
                        existingMembers = objectLikeContainer.elements;
                    }
                }
                if (typeMembers && typeMembers.length > 0) {
                    // Add filtered items to the completion list
                    symbols = filterObjectMembersList(typeMembers, existingMembers);
                }
                return true;
            }
            /**
             * Aggregates relevant symbols for completion in import clauses and export clauses
             * whose declarations have a module specifier; for instance, symbols will be aggregated for
             *
             *      import { | } from "moduleName";
             *      export { a as foo, | } from "moduleName";
             *
             * but not for
             *
             *      export { | };
             *
             * Relevant symbols are stored in the captured 'symbols' variable.
             *
             * @returns true if 'symbols' was successfully populated; false otherwise.
             */
            function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) {
                var declarationKind = namedImportsOrExports.kind === 241 /* NamedImports */ ?
                    238 /* ImportDeclaration */ :
                    244 /* ExportDeclaration */;
                var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind);
                var moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
                if (!moduleSpecifier) {
                    return false;
                }
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
                var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier);
                if (!moduleSpecifierSymbol) {
                    symbols = ts.emptyArray;
                    return true;
                }
                var exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
                symbols = filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements);
                return true;
            }
            /**
             * Aggregates relevant symbols for completion in class declaration
             * Relevant symbols are stored in the captured 'symbols' variable.
             */
            function getGetClassLikeCompletionSymbols(classLikeDeclaration) {
                // We're looking up possible property names from parent type.
                isMemberCompletion = true;
                // Declaring new property/method/accessor
                isNewIdentifierLocation = true;
                // Has keywords for class elements
                keywordFilters = 1 /* ClassElementKeywords */;
                var baseTypeNode = ts.getClassExtendsHeritageClauseElement(classLikeDeclaration);
                var implementsTypeNodes = ts.getClassImplementsHeritageClauseElements(classLikeDeclaration);
                if (baseTypeNode || implementsTypeNodes) {
                    var classElement = contextToken.parent;
                    var classElementModifierFlags = ts.isClassElement(classElement) && ts.getModifierFlags(classElement);
                    // If this is context token is not something we are editing now, consider if this would lead to be modifier
                    if (contextToken.kind === 71 /* Identifier */ && !isCurrentlyEditingNode(contextToken)) {
                        switch (contextToken.getText()) {
                            case "private":
                                classElementModifierFlags = classElementModifierFlags | 8 /* Private */;
                                break;
                            case "static":
                                classElementModifierFlags = classElementModifierFlags | 32 /* Static */;
                                break;
                        }
                    }
                    // No member list for private methods
                    if (!(classElementModifierFlags & 8 /* Private */)) {
                        var baseClassTypeToGetPropertiesFrom = void 0;
                        if (baseTypeNode) {
                            baseClassTypeToGetPropertiesFrom = typeChecker.getTypeAtLocation(baseTypeNode);
                            if (classElementModifierFlags & 32 /* Static */) {
                                // Use static class to get property symbols from
                                baseClassTypeToGetPropertiesFrom = typeChecker.getTypeOfSymbolAtLocation(baseClassTypeToGetPropertiesFrom.symbol, classLikeDeclaration);
                            }
                        }
                        var implementedInterfaceTypePropertySymbols = (classElementModifierFlags & 32 /* Static */) ?
                            ts.emptyArray :
                            ts.flatMap(implementsTypeNodes || ts.emptyArray, function (typeNode) { return typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)); });
                        // List of property symbols of base type that are not private and already implemented
                        symbols = filterClassMembersList(baseClassTypeToGetPropertiesFrom ?
                            typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) :
                            ts.emptyArray, implementedInterfaceTypePropertySymbols, classLikeDeclaration.members, classElementModifierFlags);
                    }
                }
            }
            /**
             * Returns the immediate owning object literal or binding pattern of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetObjectLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    switch (contextToken.kind) {
                        case 17 /* OpenBraceToken */: // const x = { |
                        case 26 /* CommaToken */:// const x = { a: 0, |
                            var parent = contextToken.parent;
                            if (ts.isObjectLiteralExpression(parent) || ts.isObjectBindingPattern(parent)) {
                                return parent;
                            }
                            break;
                    }
                }
                return undefined;
            }
            /**
             * Returns the containing list of named imports or exports of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetNamedImportsOrExportsForCompletion(contextToken) {
                if (contextToken) {
                    switch (contextToken.kind) {
                        case 17 /* OpenBraceToken */: // import { |
                        case 26 /* CommaToken */:// import { a as 0, |
                            switch (contextToken.parent.kind) {
                                case 241 /* NamedImports */:
                                case 245 /* NamedExports */:
                                    return contextToken.parent;
                            }
                    }
                }
                return undefined;
            }
            function isFromClassElementDeclaration(node) {
                return ts.isClassElement(node.parent) && ts.isClassLike(node.parent.parent);
            }
            function isParameterOfConstructorDeclaration(node) {
                return ts.isParameter(node) && ts.isConstructorDeclaration(node.parent);
            }
            function isConstructorParameterCompletion(node) {
                return node.parent &&
                    isParameterOfConstructorDeclaration(node.parent) &&
                    (isConstructorParameterCompletionKeyword(node.kind) || ts.isDeclarationName(node));
            }
            /**
             * Returns the immediate owning class declaration of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetClassLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    switch (contextToken.kind) {
                        case 17 /* OpenBraceToken */:// class c { |
                            if (ts.isClassLike(contextToken.parent)) {
                                return contextToken.parent;
                            }
                            break;
                        // class c {getValue(): number, | }
                        case 26 /* CommaToken */:
                            if (ts.isClassLike(contextToken.parent)) {
                                return contextToken.parent;
                            }
                            break;
                        // class c {getValue(): number; | }
                        case 25 /* SemicolonToken */:
                        // class c { method() { } | }
                        case 18 /* CloseBraceToken */:
                            if (ts.isClassLike(location)) {
                                return location;
                            }
                            // class c { method() { } b| }
                            if (isFromClassElementDeclaration(location) &&
                                location.parent.name === location) {
                                return location.parent.parent;
                            }
                            break;
                        default:
                            if (isFromClassElementDeclaration(contextToken) &&
                                (isClassMemberCompletionKeyword(contextToken.kind) ||
                                    isClassMemberCompletionKeywordText(contextToken.getText()))) {
                                return contextToken.parent.parent;
                            }
                    }
                }
                // class c { method() { } | method2() { } }
                if (location && location.kind === 286 /* SyntaxList */ && ts.isClassLike(location.parent)) {
                    return location.parent;
                }
                return undefined;
            }
            /**
             * Returns the immediate owning class declaration of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetConstructorLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    switch (contextToken.kind) {
                        case 19 /* OpenParenToken */:
                        case 26 /* CommaToken */:
                            return ts.isConstructorDeclaration(contextToken.parent) && contextToken.parent;
                        default:
                            if (isConstructorParameterCompletion(contextToken)) {
                                return contextToken.parent.parent;
                            }
                    }
                }
                return undefined;
            }
            function tryGetContainingJsxElement(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 28 /* LessThanSlashToken */:
                        case 41 /* SlashToken */:
                        case 71 /* Identifier */:
                        case 179 /* PropertyAccessExpression */:
                        case 254 /* JsxAttributes */:
                        case 253 /* JsxAttribute */:
                        case 255 /* JsxSpreadAttribute */:
                            if (parent && (parent.kind === 250 /* JsxSelfClosingElement */ || parent.kind === 251 /* JsxOpeningElement */)) {
                                return parent;
                            }
                            else if (parent.kind === 253 /* JsxAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                        // The context token is the closing } or " of an attribute, which means
                        // its parent is a JsxExpression, whose parent is a JsxAttribute,
                        // whose parent is a JsxOpeningLikeElement
                        case 9 /* StringLiteral */:
                            if (parent && ((parent.kind === 253 /* JsxAttribute */) || (parent.kind === 255 /* JsxSpreadAttribute */))) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                        case 18 /* CloseBraceToken */:
                            if (parent &&
                                parent.kind === 256 /* JsxExpression */ &&
                                parent.parent && parent.parent.kind === 253 /* JsxAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                //                  each JsxAttribute can have initializer as JsxExpression
                                return parent.parent.parent.parent;
                            }
                            if (parent && parent.kind === 255 /* JsxSpreadAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                    }
                }
                return undefined;
            }
            /**
             * @returns true if we are certain that the currently edited location must define a new location; false otherwise.
             */
            function isSolelyIdentifierDefinitionLocation(contextToken) {
                var containingNodeKind = contextToken.parent.kind;
                switch (contextToken.kind) {
                    case 26 /* CommaToken */:
                        return containingNodeKind === 226 /* VariableDeclaration */ ||
                            containingNodeKind === 227 /* VariableDeclarationList */ ||
                            containingNodeKind === 208 /* VariableStatement */ ||
                            containingNodeKind === 232 /* EnumDeclaration */ || // enum a { foo, |
                            isFunctionLikeButNotConstructor(containingNodeKind) ||
                            containingNodeKind === 230 /* InterfaceDeclaration */ || // interface A<T, |
                            containingNodeKind === 175 /* ArrayBindingPattern */ || // var [x, y|
                            containingNodeKind === 231 /* TypeAliasDeclaration */ || // type Map, K, |
                            // class A<T, |
                            // var C = class D<T, |
                            (ts.isClassLike(contextToken.parent) &&
                                contextToken.parent.typeParameters &&
                                contextToken.parent.typeParameters.end >= contextToken.pos);
                    case 23 /* DotToken */:
                        return containingNodeKind === 175 /* ArrayBindingPattern */; // var [.|
                    case 56 /* ColonToken */:
                        return containingNodeKind === 176 /* BindingElement */; // var {x :html|
                    case 21 /* OpenBracketToken */:
                        return containingNodeKind === 175 /* ArrayBindingPattern */; // var [x|
                    case 19 /* OpenParenToken */:
                        return containingNodeKind === 260 /* CatchClause */ ||
                            isFunctionLikeButNotConstructor(containingNodeKind);
                    case 17 /* OpenBraceToken */:
                        return containingNodeKind === 232 /* EnumDeclaration */ || // enum a { |
                            containingNodeKind === 230 /* InterfaceDeclaration */ || // interface a { |
                            containingNodeKind === 163 /* TypeLiteral */; // const x : { |
                    case 25 /* SemicolonToken */:
                        return containingNodeKind === 148 /* PropertySignature */ &&
                            contextToken.parent && contextToken.parent.parent &&
                            (contextToken.parent.parent.kind === 230 /* InterfaceDeclaration */ || // interface a { f; |
                                contextToken.parent.parent.kind === 163 /* TypeLiteral */); // const x : { a; |
                    case 27 /* LessThanToken */:
                        return containingNodeKind === 229 /* ClassDeclaration */ || // class A< |
                            containingNodeKind === 199 /* ClassExpression */ || // var C = class D< |
                            containingNodeKind === 230 /* InterfaceDeclaration */ || // interface A< |
                            containingNodeKind === 231 /* TypeAliasDeclaration */ || // type List< |
                            ts.isFunctionLikeKind(containingNodeKind);
                    case 115 /* StaticKeyword */:
                        return containingNodeKind === 149 /* PropertyDeclaration */ && !ts.isClassLike(contextToken.parent.parent);
                    case 24 /* DotDotDotToken */:
                        return containingNodeKind === 146 /* Parameter */ ||
                            (contextToken.parent && contextToken.parent.parent &&
                                contextToken.parent.parent.kind === 175 /* ArrayBindingPattern */); // var [...z|
                    case 114 /* PublicKeyword */:
                    case 112 /* PrivateKeyword */:
                    case 113 /* ProtectedKeyword */:
                        return containingNodeKind === 146 /* Parameter */ && !ts.isConstructorDeclaration(contextToken.parent.parent);
                    case 118 /* AsKeyword */:
                        return containingNodeKind === 242 /* ImportSpecifier */ ||
                            containingNodeKind === 246 /* ExportSpecifier */ ||
                            containingNodeKind === 240 /* NamespaceImport */;
                    case 125 /* GetKeyword */:
                    case 135 /* SetKeyword */:
                        if (isFromClassElementDeclaration(contextToken)) {
                            return false;
                        }
                    // falls through
                    case 75 /* ClassKeyword */:
                    case 83 /* EnumKeyword */:
                    case 109 /* InterfaceKeyword */:
                    case 89 /* FunctionKeyword */:
                    case 104 /* VarKeyword */:
                    case 91 /* ImportKeyword */:
                    case 110 /* LetKeyword */:
                    case 76 /* ConstKeyword */:
                    case 116 /* YieldKeyword */:
                    case 138 /* TypeKeyword */:// type htm|
                        return true;
                }
                // If the previous token is keyword correspoding to class member completion keyword
                // there will be completion available here
                if (isClassMemberCompletionKeywordText(contextToken.getText()) &&
                    isFromClassElementDeclaration(contextToken)) {
                    return false;
                }
                if (isConstructorParameterCompletion(contextToken)) {
                    // constructor parameter completion is available only if
                    // - its modifier of the constructor parameter or
                    // - its name of the parameter and not being edited
                    // eg. constructor(a |<- this shouldnt show completion
                    if (!ts.isIdentifier(contextToken) ||
                        isConstructorParameterCompletionKeywordText(contextToken.getText()) ||
                        isCurrentlyEditingNode(contextToken)) {
                        return false;
                    }
                }
                // Previous token may have been a keyword that was converted to an identifier.
                switch (contextToken.getText()) {
                    case "abstract":
                    case "async":
                    case "class":
                    case "const":
                    case "declare":
                    case "enum":
                    case "function":
                    case "interface":
                    case "let":
                    case "private":
                    case "protected":
                    case "public":
                    case "static":
                    case "var":
                    case "yield":
                        return true;
                }
                return ts.isDeclarationName(contextToken) && !ts.isJsxAttribute(contextToken.parent);
            }
            function isFunctionLikeButNotConstructor(kind) {
                return ts.isFunctionLikeKind(kind) && kind !== 152 /* Constructor */;
            }
            function isDotOfNumericLiteral(contextToken) {
                if (contextToken.kind === 8 /* NumericLiteral */) {
                    var text = contextToken.getFullText();
                    return text.charAt(text.length - 1) === ".";
                }
                return false;
            }
            /**
             * Filters out completion suggestions for named imports or exports.
             *
             * @param exportsOfModule          The list of symbols which a module exposes.
             * @param namedImportsOrExports    The list of existing import/export specifiers in the import/export clause.
             *
             * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterNamedImportOrExportCompletionItems(exportsOfModule, namedImportsOrExports) {
                var existingImportsOrExports = ts.createUnderscoreEscapedMap();
                for (var _i = 0, namedImportsOrExports_1 = namedImportsOrExports; _i < namedImportsOrExports_1.length; _i++) {
                    var element = namedImportsOrExports_1[_i];
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(element)) {
                        continue;
                    }
                    var name = element.propertyName || element.name;
                    existingImportsOrExports.set(name.escapedText, true);
                }
                if (existingImportsOrExports.size === 0) {
                    return ts.filter(exportsOfModule, function (e) { return e.escapedName !== "default"; });
                }
                return ts.filter(exportsOfModule, function (e) { return e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName); });
            }
            /**
             * Filters out completion suggestions for named imports or exports.
             *
             * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterObjectMembersList(contextualMemberSymbols, existingMembers) {
                if (!existingMembers || existingMembers.length === 0) {
                    return contextualMemberSymbols;
                }
                var existingMemberNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, existingMembers_1 = existingMembers; _i < existingMembers_1.length; _i++) {
                    var m = existingMembers_1[_i];
                    // Ignore omitted expressions for missing members
                    if (m.kind !== 261 /* PropertyAssignment */ &&
                        m.kind !== 262 /* ShorthandPropertyAssignment */ &&
                        m.kind !== 176 /* BindingElement */ &&
                        m.kind !== 151 /* MethodDeclaration */ &&
                        m.kind !== 153 /* GetAccessor */ &&
                        m.kind !== 154 /* SetAccessor */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(m)) {
                        continue;
                    }
                    var existingName = void 0;
                    if (m.kind === 176 /* BindingElement */ && m.propertyName) {
                        // include only identifiers in completion list
                        if (m.propertyName.kind === 71 /* Identifier */) {
                            existingName = m.propertyName.escapedText;
                        }
                    }
                    else {
                        // TODO: Account for computed property name
                        // NOTE: if one only performs this step when m.name is an identifier,
                        // things like '__proto__' are not filtered out.
                        var name = ts.getNameOfDeclaration(m);
                        existingName = ts.getEscapedTextOfIdentifierOrLiteral(name);
                    }
                    existingMemberNames.set(existingName, true);
                }
                return ts.filter(contextualMemberSymbols, function (m) { return !existingMemberNames.get(m.escapedName); });
            }
            /**
             * Filters out completion suggestions for class elements.
             *
             * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
             */
            function filterClassMembersList(baseSymbols, implementingTypeSymbols, existingMembers, currentClassElementModifierFlags) {
                var existingMemberNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, existingMembers_2 = existingMembers; _i < existingMembers_2.length; _i++) {
                    var m = existingMembers_2[_i];
                    // Ignore omitted expressions for missing members
                    if (m.kind !== 149 /* PropertyDeclaration */ &&
                        m.kind !== 151 /* MethodDeclaration */ &&
                        m.kind !== 153 /* GetAccessor */ &&
                        m.kind !== 154 /* SetAccessor */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(m)) {
                        continue;
                    }
                    // Dont filter member even if the name matches if it is declared private in the list
                    if (ts.hasModifier(m, 8 /* Private */)) {
                        continue;
                    }
                    // do not filter it out if the static presence doesnt match
                    var mIsStatic = ts.hasModifier(m, 32 /* Static */);
                    var currentElementIsStatic = !!(currentClassElementModifierFlags & 32 /* Static */);
                    if ((mIsStatic && !currentElementIsStatic) ||
                        (!mIsStatic && currentElementIsStatic)) {
                        continue;
                    }
                    var existingName = ts.getPropertyNameForPropertyNameNode(m.name);
                    if (existingName) {
                        existingMemberNames.set(existingName, true);
                    }
                }
                var result = [];
                addPropertySymbols(baseSymbols, 8 /* Private */);
                addPropertySymbols(implementingTypeSymbols, 24 /* NonPublicAccessibilityModifier */);
                return result;
                function addPropertySymbols(properties, inValidModifierFlags) {
                    for (var _i = 0, properties_12 = properties; _i < properties_12.length; _i++) {
                        var property = properties_12[_i];
                        if (isValidProperty(property, inValidModifierFlags)) {
                            result.push(property);
                        }
                    }
                }
                function isValidProperty(propertySymbol, inValidModifierFlags) {
                    return !existingMemberNames.get(propertySymbol.escapedName) &&
                        propertySymbol.getDeclarations() &&
                        !(ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & inValidModifierFlags);
                }
            }
            /**
             * Filters out completion suggestions from 'symbols' according to existing JSX attributes.
             *
             * @returns Symbols to be suggested in a JSX element, barring those whose attributes
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterJsxAttributes(symbols, attributes) {
                var seenNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) {
                    var attr = attributes_1[_i];
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(attr)) {
                        continue;
                    }
                    if (attr.kind === 253 /* JsxAttribute */) {
                        seenNames.set(attr.name.escapedText, true);
                    }
                }
                return ts.filter(symbols, function (a) { return !seenNames.get(a.escapedName); });
            }
            function isCurrentlyEditingNode(node) {
                return node.getStart() <= position && position <= node.getEnd();
            }
        }
        /**
         * Get the name to be display in completion from a given symbol.
         *
         * @return undefined if the name is of external module
         */
        function getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral) {
            var name = symbol.name;
            if (!name)
                return undefined;
            // First check of the displayName is not external module; if it is an external module, it is not valid entry
            if (symbol.flags & 1920 /* Namespace */) {
                var firstCharCode = name.charCodeAt(0);
                if (ts.isSingleOrDoubleQuote(firstCharCode)) {
                    // If the symbol is external module, don't show it in the completion list
                    // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there)
                    return undefined;
                }
            }
            return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral);
        }
        /**
         * Get a displayName from a given for completion list, performing any necessary quotes stripping
         * and checking whether the name is valid identifier name.
         */
        function getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral) {
            // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
            // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
            // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid.
            // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name.
            if (performCharacterChecks && !ts.isIdentifierText(name, target)) {
                // TODO: GH#18169
                return allowStringLiteral ? JSON.stringify(name) : undefined;
            }
            return name;
        }
        // A cache of completion entries for keywords, these do not change between sessions
        var _keywordCompletions = [];
        function getKeywordCompletions(keywordFilter) {
            var completions = _keywordCompletions[keywordFilter];
            if (completions) {
                return completions;
            }
            return _keywordCompletions[keywordFilter] = generateKeywordCompletions(keywordFilter);
            function generateKeywordCompletions(keywordFilter) {
                switch (keywordFilter) {
                    case 0 /* None */:
                        return getAllKeywordCompletions();
                    case 1 /* ClassElementKeywords */:
                        return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText);
                    case 2 /* ConstructorParameterKeywords */:
                        return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText);
                }
            }
            function getAllKeywordCompletions() {
                var allKeywordsCompletions = [];
                for (var i = 72 /* FirstKeyword */; i <= 142 /* LastKeyword */; i++) {
                    allKeywordsCompletions.push({
                        name: ts.tokenToString(i),
                        kind: "keyword" /* keyword */,
                        kindModifiers: "" /* none */,
                        sortText: "0"
                    });
                }
                return allKeywordsCompletions;
            }
            function getFilteredKeywordCompletions(filterFn) {
                return ts.filter(getKeywordCompletions(0 /* None */), function (entry) { return filterFn(entry.name); });
            }
        }
        function isClassMemberCompletionKeyword(kind) {
            switch (kind) {
                case 114 /* PublicKeyword */:
                case 113 /* ProtectedKeyword */:
                case 112 /* PrivateKeyword */:
                case 117 /* AbstractKeyword */:
                case 115 /* StaticKeyword */:
                case 123 /* ConstructorKeyword */:
                case 131 /* ReadonlyKeyword */:
                case 125 /* GetKeyword */:
                case 135 /* SetKeyword */:
                case 120 /* AsyncKeyword */:
                    return true;
            }
        }
        function isClassMemberCompletionKeywordText(text) {
            return isClassMemberCompletionKeyword(ts.stringToToken(text));
        }
        function isConstructorParameterCompletionKeyword(kind) {
            switch (kind) {
                case 114 /* PublicKeyword */:
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 131 /* ReadonlyKeyword */:
                    return true;
            }
        }
        function isConstructorParameterCompletionKeywordText(text) {
            return isConstructorParameterCompletionKeyword(ts.stringToToken(text));
        }
        function isEqualityExpression(node) {
            return ts.isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
        }
        function isEqualityOperatorKind(kind) {
            return kind === 32 /* EqualsEqualsToken */ ||
                kind === 33 /* ExclamationEqualsToken */ ||
                kind === 34 /* EqualsEqualsEqualsToken */ ||
                kind === 35 /* ExclamationEqualsEqualsToken */;
        }
        /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */
        function getJsDocTagAtPosition(node, position) {
            var jsDoc = getJsDocHavingNode(node).jsDoc;
            if (!jsDoc)
                return undefined;
            for (var _i = 0, jsDoc_1 = jsDoc; _i < jsDoc_1.length; _i++) {
                var _a = jsDoc_1[_i], pos = _a.pos, end = _a.end, tags = _a.tags;
                if (!tags || position < pos || position > end)
                    continue;
                for (var i = tags.length - 1; i >= 0; i--) {
                    var tag = tags[i];
                    if (position >= tag.pos) {
                        return tag;
                    }
                }
            }
        }
        function getJsDocHavingNode(node) {
            if (!ts.isToken(node))
                return node;
            switch (node.kind) {
                case 104 /* VarKeyword */:
                case 110 /* LetKeyword */:
                case 76 /* ConstKeyword */:
                    // if the current token is var, let or const, skip the VariableDeclarationList
                    return node.parent.parent;
                default:
                    return node.parent;
            }
        }
        /**
         * Gets all properties on a type, but if that type is a union of several types,
         * tries to only include those types which declare properties, not methods.
         * This ensures that we don't try providing completions for all the methods on e.g. Array.
         */
        function getPropertiesForCompletion(type, checker) {
            if (!(type.flags & 65536 /* Union */)) {
                return checker.getPropertiesOfType(type);
            }
            var types = type.types;
            var filteredTypes = types.filter(function (memberType) { return !(memberType.flags & 8190 /* Primitive */ || checker.isArrayLikeType(memberType)); });
            // If there are no property-only types, just provide completions for every type as usual.
            return checker.getAllPossiblePropertiesOfTypes(filteredTypes);
        }
    })(Completions = ts.Completions || (ts.Completions = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var DocumentHighlights;
    (function (DocumentHighlights) {
        function getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch) {
            var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
            // Note that getTouchingWord indicates failure by returning the sourceFile node.
            if (node === sourceFile)
                return undefined;
            ts.Debug.assert(node.parent !== undefined);
            if (ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node || ts.isJsxClosingElement(node.parent)) {
                // For a JSX element, just highlight the matching tag, not all references.
                var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement;
                var highlightSpans = [openingElement, closingElement].map(function (_a) {
                    var tagName = _a.tagName;
                    return getHighlightSpanForNode(tagName, sourceFile);
                });
                return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
            }
            return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile);
        }
        DocumentHighlights.getDocumentHighlights = getDocumentHighlights;
        function getHighlightSpanForNode(node, sourceFile) {
            return {
                fileName: sourceFile.fileName,
                textSpan: ts.createTextSpanFromNode(node, sourceFile),
                kind: "none" /* none */
            };
        }
        function getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) {
            var referenceEntries = ts.FindAllReferences.getReferenceEntriesForNode(node, program, sourceFilesToSearch, cancellationToken);
            return referenceEntries && convertReferencedSymbols(referenceEntries);
        }
        function convertReferencedSymbols(referenceEntries) {
            var fileNameToDocumentHighlights = ts.createMap();
            for (var _i = 0, referenceEntries_1 = referenceEntries; _i < referenceEntries_1.length; _i++) {
                var entry = referenceEntries_1[_i];
                var _a = ts.FindAllReferences.toHighlightSpan(entry), fileName = _a.fileName, span_12 = _a.span;
                var highlightSpans = fileNameToDocumentHighlights.get(fileName);
                if (!highlightSpans) {
                    fileNameToDocumentHighlights.set(fileName, highlightSpans = []);
                }
                highlightSpans.push(span_12);
            }
            return ts.arrayFrom(fileNameToDocumentHighlights.entries(), function (_a) {
                var fileName = _a[0], highlightSpans = _a[1];
                return ({ fileName: fileName, highlightSpans: highlightSpans });
            });
        }
        function getSyntacticDocumentHighlights(node, sourceFile) {
            var highlightSpans = getHighlightSpans(node, sourceFile);
            if (!highlightSpans || highlightSpans.length === 0) {
                return undefined;
            }
            return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
        }
        // returns true if 'node' is defined and has a matching 'kind'.
        function hasKind(node, kind) {
            return node !== undefined && node.kind === kind;
        }
        // Null-propagating 'parent' function.
        function parent(node) {
            return node && node.parent;
        }
        function getHighlightSpans(node, sourceFile) {
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 90 /* IfKeyword */:
                case 82 /* ElseKeyword */:
                    if (hasKind(node.parent, 211 /* IfStatement */)) {
                        return getIfElseOccurrences(node.parent, sourceFile);
                    }
                    break;
                case 96 /* ReturnKeyword */:
                    if (hasKind(node.parent, 219 /* ReturnStatement */)) {
                        return highlightSpans(getReturnOccurrences(node.parent));
                    }
                    break;
                case 100 /* ThrowKeyword */:
                    if (hasKind(node.parent, 223 /* ThrowStatement */)) {
                        return highlightSpans(getThrowOccurrences(node.parent));
                    }
                    break;
                case 102 /* TryKeyword */:
                case 74 /* CatchKeyword */:
                case 87 /* FinallyKeyword */:
                    var tryStatement = node.kind === 74 /* CatchKeyword */ ? parent(parent(node)) : parent(node);
                    if (hasKind(tryStatement, 224 /* TryStatement */)) {
                        return highlightSpans(getTryCatchFinallyOccurrences(tryStatement, sourceFile));
                    }
                    break;
                case 98 /* SwitchKeyword */:
                    if (hasKind(node.parent, 221 /* SwitchStatement */)) {
                        return highlightSpans(getSwitchCaseDefaultOccurrences(node.parent));
                    }
                    break;
                case 73 /* CaseKeyword */:
                case 79 /* DefaultKeyword */:
                    if (hasKind(parent(parent(parent(node))), 221 /* SwitchStatement */)) {
                        return highlightSpans(getSwitchCaseDefaultOccurrences(node.parent.parent.parent));
                    }
                    break;
                case 72 /* BreakKeyword */:
                case 77 /* ContinueKeyword */:
                    if (hasKind(node.parent, 218 /* BreakStatement */) || hasKind(node.parent, 217 /* ContinueStatement */)) {
                        return highlightSpans(getBreakOrContinueStatementOccurrences(node.parent));
                    }
                    break;
                case 88 /* ForKeyword */:
                    if (hasKind(node.parent, 214 /* ForStatement */) ||
                        hasKind(node.parent, 215 /* ForInStatement */) ||
                        hasKind(node.parent, 216 /* ForOfStatement */)) {
                        return highlightSpans(getLoopBreakContinueOccurrences(node.parent));
                    }
                    break;
                case 106 /* WhileKeyword */:
                case 81 /* DoKeyword */:
                    if (hasKind(node.parent, 213 /* WhileStatement */) || hasKind(node.parent, 212 /* DoStatement */)) {
                        return highlightSpans(getLoopBreakContinueOccurrences(node.parent));
                    }
                    break;
                case 123 /* ConstructorKeyword */:
                    if (hasKind(node.parent, 152 /* Constructor */)) {
                        return highlightSpans(getConstructorOccurrences(node.parent));
                    }
                    break;
                case 125 /* GetKeyword */:
                case 135 /* SetKeyword */:
                    if (hasKind(node.parent, 153 /* GetAccessor */) || hasKind(node.parent, 154 /* SetAccessor */)) {
                        return highlightSpans(getGetAndSetOccurrences(node.parent));
                    }
                    break;
                default:
                    if (ts.isModifierKind(node.kind) && node.parent &&
                        (ts.isDeclaration(node.parent) || node.parent.kind === 208 /* VariableStatement */)) {
                        return highlightSpans(getModifierOccurrences(node.kind, node.parent));
                    }
            }
            function highlightSpans(nodes) {
                return nodes && nodes.map(function (node) { return getHighlightSpanForNode(node, sourceFile); });
            }
        }
        /**
         * Aggregates all throw-statements within this node *without* crossing
         * into function boundaries and try-blocks with catch-clauses.
         */
        function aggregateOwnedThrowStatements(node) {
            var statementAccumulator = [];
            aggregate(node);
            return statementAccumulator;
            function aggregate(node) {
                if (node.kind === 223 /* ThrowStatement */) {
                    statementAccumulator.push(node);
                }
                else if (node.kind === 224 /* TryStatement */) {
                    var tryStatement = node;
                    if (tryStatement.catchClause) {
                        aggregate(tryStatement.catchClause);
                    }
                    else {
                        // Exceptions thrown within a try block lacking a catch clause
                        // are "owned" in the current context.
                        aggregate(tryStatement.tryBlock);
                    }
                    if (tryStatement.finallyBlock) {
                        aggregate(tryStatement.finallyBlock);
                    }
                }
                else if (!ts.isFunctionLike(node)) {
                    ts.forEachChild(node, aggregate);
                }
            }
        }
        /**
         * For lack of a better name, this function takes a throw statement and returns the
         * nearest ancestor that is a try-block (whose try statement has a catch clause),
         * function-block, or source file.
         */
        function getThrowStatementOwner(throwStatement) {
            var child = throwStatement;
            while (child.parent) {
                var parent_2 = child.parent;
                if (ts.isFunctionBlock(parent_2) || parent_2.kind === 265 /* SourceFile */) {
                    return parent_2;
                }
                // A throw-statement is only owned by a try-statement if the try-statement has
                // a catch clause, and if the throw-statement occurs within the try block.
                if (parent_2.kind === 224 /* TryStatement */) {
                    var tryStatement = parent_2;
                    if (tryStatement.tryBlock === child && tryStatement.catchClause) {
                        return child;
                    }
                }
                child = parent_2;
            }
            return undefined;
        }
        function aggregateAllBreakAndContinueStatements(node) {
            var statementAccumulator = [];
            aggregate(node);
            return statementAccumulator;
            function aggregate(node) {
                if (node.kind === 218 /* BreakStatement */ || node.kind === 217 /* ContinueStatement */) {
                    statementAccumulator.push(node);
                }
                else if (!ts.isFunctionLike(node)) {
                    ts.forEachChild(node, aggregate);
                }
            }
        }
        function ownsBreakOrContinueStatement(owner, statement) {
            var actualOwner = getBreakOrContinueOwner(statement);
            return actualOwner && actualOwner === owner;
        }
        function getBreakOrContinueOwner(statement) {
            for (var node = statement.parent; node; node = node.parent) {
                switch (node.kind) {
                    case 221 /* SwitchStatement */:
                        if (statement.kind === 217 /* ContinueStatement */) {
                            continue;
                        }
                    // falls through
                    case 214 /* ForStatement */:
                    case 215 /* ForInStatement */:
                    case 216 /* ForOfStatement */:
                    case 213 /* WhileStatement */:
                    case 212 /* DoStatement */:
                        if (!statement.label || isLabeledBy(node, statement.label.text)) {
                            return node;
                        }
                        break;
                    default:
                        // Don't cross function boundaries.
                        if (ts.isFunctionLike(node)) {
                            return undefined;
                        }
                        break;
                }
            }
            return undefined;
        }
        function getModifierOccurrences(modifier, declaration) {
            // Make sure we only highlight the keyword when it makes sense to do so.
            if (!isLegalModifier(modifier, declaration)) {
                return undefined;
            }
            var modifierFlag = ts.modifierToFlag(modifier);
            return ts.mapDefined(getNodesToSearchForModifier(declaration, modifierFlag), function (node) {
                if (ts.getModifierFlags(node) & modifierFlag) {
                    var mod = ts.find(node.modifiers, function (m) { return m.kind === modifier; });
                    ts.Debug.assert(!!mod);
                    return mod;
                }
            });
        }
        function getNodesToSearchForModifier(declaration, modifierFlag) {
            var container = declaration.parent;
            switch (container.kind) {
                case 234 /* ModuleBlock */:
                case 265 /* SourceFile */:
                case 207 /* Block */:
                case 257 /* CaseClause */:
                case 258 /* DefaultClause */:
                    // Container is either a class declaration or the declaration is a classDeclaration
                    if (modifierFlag & 128 /* Abstract */) {
                        return declaration.members.concat([declaration]);
                    }
                    else {
                        return container.statements;
                    }
                case 152 /* Constructor */:
                    return container.parameters.concat(container.parent.members);
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                    var nodes = container.members;
                    // If we're an accessibility modifier, we're in an instance member and should search
                    // the constructor's parameter list for instance members as well.
                    if (modifierFlag & 28 /* AccessibilityModifier */) {
                        var constructor = ts.find(container.members, ts.isConstructorDeclaration);
                        if (constructor) {
                            return nodes.concat(constructor.parameters);
                        }
                    }
                    else if (modifierFlag & 128 /* Abstract */) {
                        return nodes.concat([container]);
                    }
                    return nodes;
                default:
                    ts.Debug.fail("Invalid container kind.");
            }
        }
        function isLegalModifier(modifier, declaration) {
            var container = declaration.parent;
            switch (modifier) {
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 114 /* PublicKeyword */:
                    switch (container.kind) {
                        case 229 /* ClassDeclaration */:
                        case 199 /* ClassExpression */:
                            return true;
                        case 152 /* Constructor */:
                            return declaration.kind === 146 /* Parameter */;
                        default:
                            return false;
                    }
                case 115 /* StaticKeyword */:
                    return container.kind === 229 /* ClassDeclaration */ || container.kind === 199 /* ClassExpression */;
                case 84 /* ExportKeyword */:
                case 124 /* DeclareKeyword */:
                    return container.kind === 234 /* ModuleBlock */ || container.kind === 265 /* SourceFile */;
                case 117 /* AbstractKeyword */:
                    return container.kind === 229 /* ClassDeclaration */ || declaration.kind === 229 /* ClassDeclaration */;
                default:
                    return false;
            }
        }
        function pushKeywordIf(keywordList, token) {
            var expected = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                expected[_i - 2] = arguments[_i];
            }
            if (token && ts.contains(expected, token.kind)) {
                keywordList.push(token);
                return true;
            }
            return false;
        }
        function getGetAndSetOccurrences(accessorDeclaration) {
            var keywords = [];
            tryPushAccessorKeyword(accessorDeclaration.symbol, 153 /* GetAccessor */);
            tryPushAccessorKeyword(accessorDeclaration.symbol, 154 /* SetAccessor */);
            return keywords;
            function tryPushAccessorKeyword(accessorSymbol, accessorKind) {
                var accessor = ts.getDeclarationOfKind(accessorSymbol, accessorKind);
                if (accessor) {
                    ts.forEach(accessor.getChildren(), function (child) { return pushKeywordIf(keywords, child, 125 /* GetKeyword */, 135 /* SetKeyword */); });
                }
            }
        }
        function getConstructorOccurrences(constructorDeclaration) {
            var declarations = constructorDeclaration.symbol.getDeclarations();
            var keywords = [];
            ts.forEach(declarations, function (declaration) {
                ts.forEach(declaration.getChildren(), function (token) {
                    return pushKeywordIf(keywords, token, 123 /* ConstructorKeyword */);
                });
            });
            return keywords;
        }
        function getLoopBreakContinueOccurrences(loopNode) {
            var keywords = [];
            if (pushKeywordIf(keywords, loopNode.getFirstToken(), 88 /* ForKeyword */, 106 /* WhileKeyword */, 81 /* DoKeyword */)) {
                // If we succeeded and got a do-while loop, then start looking for a 'while' keyword.
                if (loopNode.kind === 212 /* DoStatement */) {
                    var loopTokens = loopNode.getChildren();
                    for (var i = loopTokens.length - 1; i >= 0; i--) {
                        if (pushKeywordIf(keywords, loopTokens[i], 106 /* WhileKeyword */)) {
                            break;
                        }
                    }
                }
            }
            var breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement);
            ts.forEach(breaksAndContinues, function (statement) {
                if (ownsBreakOrContinueStatement(loopNode, statement)) {
                    pushKeywordIf(keywords, statement.getFirstToken(), 72 /* BreakKeyword */, 77 /* ContinueKeyword */);
                }
            });
            return keywords;
        }
        function getBreakOrContinueStatementOccurrences(breakOrContinueStatement) {
            var owner = getBreakOrContinueOwner(breakOrContinueStatement);
            if (owner) {
                switch (owner.kind) {
                    case 214 /* ForStatement */:
                    case 215 /* ForInStatement */:
                    case 216 /* ForOfStatement */:
                    case 212 /* DoStatement */:
                    case 213 /* WhileStatement */:
                        return getLoopBreakContinueOccurrences(owner);
                    case 221 /* SwitchStatement */:
                        return getSwitchCaseDefaultOccurrences(owner);
                }
            }
            return undefined;
        }
        function getSwitchCaseDefaultOccurrences(switchStatement) {
            var keywords = [];
            pushKeywordIf(keywords, switchStatement.getFirstToken(), 98 /* SwitchKeyword */);
            // Go through each clause in the switch statement, collecting the 'case'/'default' keywords.
            ts.forEach(switchStatement.caseBlock.clauses, function (clause) {
                pushKeywordIf(keywords, clause.getFirstToken(), 73 /* CaseKeyword */, 79 /* DefaultKeyword */);
                var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause);
                ts.forEach(breaksAndContinues, function (statement) {
                    if (ownsBreakOrContinueStatement(switchStatement, statement)) {
                        pushKeywordIf(keywords, statement.getFirstToken(), 72 /* BreakKeyword */);
                    }
                });
            });
            return keywords;
        }
        function getTryCatchFinallyOccurrences(tryStatement, sourceFile) {
            var keywords = [];
            pushKeywordIf(keywords, tryStatement.getFirstToken(), 102 /* TryKeyword */);
            if (tryStatement.catchClause) {
                pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), 74 /* CatchKeyword */);
            }
            if (tryStatement.finallyBlock) {
                var finallyKeyword = ts.findChildOfKind(tryStatement, 87 /* FinallyKeyword */, sourceFile);
                pushKeywordIf(keywords, finallyKeyword, 87 /* FinallyKeyword */);
            }
            return keywords;
        }
        function getThrowOccurrences(throwStatement) {
            var owner = getThrowStatementOwner(throwStatement);
            if (!owner) {
                return undefined;
            }
            var keywords = [];
            ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) {
                pushKeywordIf(keywords, throwStatement.getFirstToken(), 100 /* ThrowKeyword */);
            });
            // If the "owner" is a function, then we equate 'return' and 'throw' statements in their
            // ability to "jump out" of the function, and include occurrences for both.
            if (ts.isFunctionBlock(owner)) {
                ts.forEachReturnStatement(owner, function (returnStatement) {
                    pushKeywordIf(keywords, returnStatement.getFirstToken(), 96 /* ReturnKeyword */);
                });
            }
            return keywords;
        }
        function getReturnOccurrences(returnStatement) {
            var func = ts.getContainingFunction(returnStatement);
            // If we didn't find a containing function with a block body, bail out.
            if (!(func && hasKind(func.body, 207 /* Block */))) {
                return undefined;
            }
            var keywords = [];
            ts.forEachReturnStatement(func.body, function (returnStatement) {
                pushKeywordIf(keywords, returnStatement.getFirstToken(), 96 /* ReturnKeyword */);
            });
            // Include 'throw' statements that do not occur within a try block.
            ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) {
                pushKeywordIf(keywords, throwStatement.getFirstToken(), 100 /* ThrowKeyword */);
            });
            return keywords;
        }
        function getIfElseOccurrences(ifStatement, sourceFile) {
            var keywords = [];
            // Traverse upwards through all parent if-statements linked by their else-branches.
            while (hasKind(ifStatement.parent, 211 /* IfStatement */) && ifStatement.parent.elseStatement === ifStatement) {
                ifStatement = ifStatement.parent;
            }
            // Now traverse back down through the else branches, aggregating if/else keywords of if-statements.
            while (ifStatement) {
                var children = ifStatement.getChildren();
                pushKeywordIf(keywords, children[0], 90 /* IfKeyword */);
                // Generally the 'else' keyword is second-to-last, so we traverse backwards.
                for (var i = children.length - 1; i >= 0; i--) {
                    if (pushKeywordIf(keywords, children[i], 82 /* ElseKeyword */)) {
                        break;
                    }
                }
                if (!hasKind(ifStatement.elseStatement, 211 /* IfStatement */)) {
                    break;
                }
                ifStatement = ifStatement.elseStatement;
            }
            var result = [];
            // We'd like to highlight else/ifs together if they are only separated by whitespace
            // (i.e. the keywords are separated by no comments, no newlines).
            for (var i = 0; i < keywords.length; i++) {
                if (keywords[i].kind === 82 /* ElseKeyword */ && i < keywords.length - 1) {
                    var elseKeyword = keywords[i];
                    var ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword.
                    var shouldCombindElseAndIf = true;
                    // Avoid recalculating getStart() by iterating backwards.
                    for (var j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) {
                        if (!ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) {
                            shouldCombindElseAndIf = false;
                            break;
                        }
                    }
                    if (shouldCombindElseAndIf) {
                        result.push({
                            fileName: sourceFile.fileName,
                            textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end),
                            kind: "reference" /* reference */
                        });
                        i++; // skip the next keyword
                        continue;
                    }
                }
                // Ordinary case: just highlight the keyword.
                result.push(getHighlightSpanForNode(keywords[i], sourceFile));
            }
            return result;
        }
        /**
         * Whether or not a 'node' is preceded by a label of the given string.
         * Note: 'node' cannot be a SourceFile.
         */
        function isLabeledBy(node, labelName) {
            for (var owner = node.parent; owner.kind === 222 /* LabeledStatement */; owner = owner.parent) {
                if (owner.label.escapedText === labelName) {
                    return true;
                }
            }
            return false;
        }
    })(DocumentHighlights = ts.DocumentHighlights || (ts.DocumentHighlights = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory) {
        if (currentDirectory === void 0) { currentDirectory = ""; }
        // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
        // for those settings.
        var buckets = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(!!useCaseSensitiveFileNames);
        function getKeyForCompilationSettings(settings) {
            return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + "|" + settings.allowJs + "|" + settings.baseUrl + "|" + JSON.stringify(settings.typeRoots) + "|" + JSON.stringify(settings.rootDirs) + "|" + JSON.stringify(settings.paths);
        }
        function getBucketForCompilationSettings(key, createIfMissing) {
            var bucket = buckets.get(key);
            if (!bucket && createIfMissing) {
                buckets.set(key, bucket = ts.createMap());
            }
            return bucket;
        }
        function reportStats() {
            var bucketInfoArray = ts.arrayFrom(buckets.keys()).filter(function (name) { return name && name.charAt(0) === "_"; }).map(function (name) {
                var entries = buckets.get(name);
                var sourceFiles = [];
                entries.forEach(function (entry, name) {
                    sourceFiles.push({
                        name: name,
                        refCount: entry.languageServiceRefCount,
                        references: entry.owners.slice(0)
                    });
                });
                sourceFiles.sort(function (x, y) { return y.refCount - x.refCount; });
                return {
                    bucket: name,
                    sourceFiles: sourceFiles
                };
            });
            return JSON.stringify(bucketInfoArray, undefined, 2);
        }
        function acquireDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
        }
        function acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ true, scriptKind);
        }
        function updateDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
        }
        function updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ false, scriptKind);
        }
        function acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, acquiring, scriptKind) {
            var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
            var entry = bucket.get(path);
            if (!entry) {
                // Have never seen this file with these settings.  Create a new source file for it.
                var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
                entry = {
                    sourceFile: sourceFile,
                    languageServiceRefCount: 1,
                    owners: []
                };
                bucket.set(path, entry);
            }
            else {
                // We have an entry for this file.  However, it may be for a different version of
                // the script snapshot.  If so, update it appropriately.  Otherwise, we can just
                // return it as is.
                if (entry.sourceFile.version !== version) {
                    entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
                }
                // If we're acquiring, then this is the first time this LS is asking for this document.
                // Increase our ref count so we know there's another LS using the document.  If we're
                // not acquiring, then that means the LS is 'updating' the file instead, and that means
                // it has already acquired the document previously.  As such, we do not need to increase
                // the ref count.
                if (acquiring) {
                    entry.languageServiceRefCount++;
                }
            }
            return entry.sourceFile;
        }
        function releaseDocument(fileName, compilationSettings) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return releaseDocumentWithKey(path, key);
        }
        function releaseDocumentWithKey(path, key) {
            var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ false);
            ts.Debug.assert(bucket !== undefined);
            var entry = bucket.get(path);
            entry.languageServiceRefCount--;
            ts.Debug.assert(entry.languageServiceRefCount >= 0);
            if (entry.languageServiceRefCount === 0) {
                bucket.delete(path);
            }
        }
        return {
            acquireDocument: acquireDocument,
            acquireDocumentWithKey: acquireDocumentWithKey,
            updateDocument: updateDocument,
            updateDocumentWithKey: updateDocumentWithKey,
            releaseDocument: releaseDocument,
            releaseDocumentWithKey: releaseDocumentWithKey,
            reportStats: reportStats,
            getKeyForCompilationSettings: getKeyForCompilationSettings
        };
    }
    ts.createDocumentRegistry = createDocumentRegistry;
})(ts || (ts = {}));
/* Code for finding imports of an exported symbol. Used only by FindAllReferences. */
/* @internal */
var ts;
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        /** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily.  */
        function createImportTracker(sourceFiles, checker, cancellationToken) {
            var allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken);
            return function (exportSymbol, exportInfo, isForRename) {
                var _a = getImportersForExport(sourceFiles, allDirectImports, exportInfo, checker, cancellationToken), directImports = _a.directImports, indirectUsers = _a.indirectUsers;
                return __assign({ indirectUsers: indirectUsers }, getSearchesFromDirectImports(directImports, exportSymbol, exportInfo.exportKind, checker, isForRename));
            };
        }
        FindAllReferences.createImportTracker = createImportTracker;
        var ExportKind;
        (function (ExportKind) {
            ExportKind[ExportKind["Named"] = 0] = "Named";
            ExportKind[ExportKind["Default"] = 1] = "Default";
            ExportKind[ExportKind["ExportEquals"] = 2] = "ExportEquals";
        })(ExportKind = FindAllReferences.ExportKind || (FindAllReferences.ExportKind = {}));
        var ImportExport;
        (function (ImportExport) {
            ImportExport[ImportExport["Import"] = 0] = "Import";
            ImportExport[ImportExport["Export"] = 1] = "Export";
        })(ImportExport = FindAllReferences.ImportExport || (FindAllReferences.ImportExport = {}));
        /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
        function getImportersForExport(sourceFiles, allDirectImports, _a, checker, cancellationToken) {
            var exportingModuleSymbol = _a.exportingModuleSymbol, exportKind = _a.exportKind;
            var markSeenDirectImport = ts.nodeSeenTracker();
            var markSeenIndirectUser = ts.nodeSeenTracker();
            var directImports = [];
            var isAvailableThroughGlobal = !!exportingModuleSymbol.globalExports;
            var indirectUserDeclarations = isAvailableThroughGlobal ? undefined : [];
            handleDirectImports(exportingModuleSymbol);
            return { directImports: directImports, indirectUsers: getIndirectUsers() };
            function getIndirectUsers() {
                if (isAvailableThroughGlobal) {
                    // It has `export as namespace`, so anything could potentially use it.
                    return sourceFiles;
                }
                // Module augmentations may use this module's exports without importing it.
                for (var _i = 0, _a = exportingModuleSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (ts.isExternalModuleAugmentation(decl)) {
                        addIndirectUser(decl);
                    }
                }
                // This may return duplicates (if there are multiple module declarations in a single source file, all importing the same thing as a namespace), but `State.markSearchedSymbol` will handle that.
                return indirectUserDeclarations.map(ts.getSourceFileOfNode);
            }
            function handleDirectImports(exportingModuleSymbol) {
                var theseDirectImports = getDirectImports(exportingModuleSymbol);
                if (theseDirectImports) {
                    for (var _i = 0, theseDirectImports_1 = theseDirectImports; _i < theseDirectImports_1.length; _i++) {
                        var direct = theseDirectImports_1[_i];
                        if (!markSeenDirectImport(direct)) {
                            continue;
                        }
                        cancellationToken.throwIfCancellationRequested();
                        switch (direct.kind) {
                            case 181 /* CallExpression */:
                                if (!isAvailableThroughGlobal) {
                                    var parent = direct.parent;
                                    if (exportKind === 2 /* ExportEquals */ && parent.kind === 226 /* VariableDeclaration */) {
                                        var name = parent.name;
                                        if (name.kind === 71 /* Identifier */) {
                                            directImports.push(name);
                                            break;
                                        }
                                    }
                                    // Don't support re-exporting 'require()' calls, so just add a single indirect user.
                                    addIndirectUser(direct.getSourceFile());
                                }
                                break;
                            case 237 /* ImportEqualsDeclaration */:
                                handleNamespaceImport(direct, direct.name, ts.hasModifier(direct, 1 /* Export */));
                                break;
                            case 238 /* ImportDeclaration */:
                                var namedBindings = direct.importClause && direct.importClause.namedBindings;
                                if (namedBindings && namedBindings.kind === 240 /* NamespaceImport */) {
                                    handleNamespaceImport(direct, namedBindings.name);
                                }
                                else {
                                    directImports.push(direct);
                                }
                                break;
                            case 244 /* ExportDeclaration */:
                                if (!direct.exportClause) {
                                    // This is `export * from "foo"`, so imports of this module may import the export too.
                                    handleDirectImports(getContainingModuleSymbol(direct, checker));
                                }
                                else {
                                    // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports.
                                    directImports.push(direct);
                                }
                                break;
                        }
                    }
                }
            }
            function handleNamespaceImport(importDeclaration, name, isReExport) {
                if (exportKind === 2 /* ExportEquals */) {
                    // This is a direct import, not import-as-namespace.
                    directImports.push(importDeclaration);
                }
                else if (!isAvailableThroughGlobal) {
                    var sourceFileLike = getSourceFileLikeForImportDeclaration(importDeclaration);
                    ts.Debug.assert(sourceFileLike.kind === 265 /* SourceFile */ || sourceFileLike.kind === 233 /* ModuleDeclaration */);
                    if (isReExport || findNamespaceReExports(sourceFileLike, name, checker)) {
                        addIndirectUsers(sourceFileLike);
                    }
                    else {
                        addIndirectUser(sourceFileLike);
                    }
                }
            }
            function addIndirectUser(sourceFileLike) {
                ts.Debug.assert(!isAvailableThroughGlobal);
                var isNew = markSeenIndirectUser(sourceFileLike);
                if (isNew) {
                    indirectUserDeclarations.push(sourceFileLike);
                }
                return isNew;
            }
            /** Adds a module and all of its transitive dependencies as possible indirect users. */
            function addIndirectUsers(sourceFileLike) {
                if (!addIndirectUser(sourceFileLike)) {
                    return;
                }
                var moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol);
                ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
                var directImports = getDirectImports(moduleSymbol);
                if (directImports) {
                    for (var _i = 0, directImports_1 = directImports; _i < directImports_1.length; _i++) {
                        var directImport = directImports_1[_i];
                        addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport));
                    }
                }
            }
            function getDirectImports(moduleSymbol) {
                return allDirectImports.get(ts.getSymbolId(moduleSymbol).toString());
            }
        }
        /**
         * Given the set of direct imports of a module, we need to find which ones import the particular exported symbol.
         * The returned `importSearches` will result in the entire source file being searched.
         * But re-exports will be placed in 'singleReferences' since they cannot be locally referenced.
         */
        function getSearchesFromDirectImports(directImports, exportSymbol, exportKind, checker, isForRename) {
            var importSearches = [];
            var singleReferences = [];
            function addSearch(location, symbol) {
                importSearches.push([location, symbol]);
            }
            if (directImports) {
                for (var _i = 0, directImports_2 = directImports; _i < directImports_2.length; _i++) {
                    var decl = directImports_2[_i];
                    handleImport(decl);
                }
            }
            return { importSearches: importSearches, singleReferences: singleReferences };
            function handleImport(decl) {
                if (decl.kind === 237 /* ImportEqualsDeclaration */) {
                    if (isExternalModuleImportEquals(decl)) {
                        handleNamespaceImportLike(decl.name);
                    }
                    return;
                }
                if (decl.kind === 71 /* Identifier */) {
                    handleNamespaceImportLike(decl);
                    return;
                }
                // Ignore if there's a grammar error
                if (decl.moduleSpecifier.kind !== 9 /* StringLiteral */) {
                    return;
                }
                if (decl.kind === 244 /* ExportDeclaration */) {
                    searchForNamedImport(decl.exportClause);
                    return;
                }
                var importClause = decl.importClause;
                if (!importClause) {
                    return;
                }
                var namedBindings = importClause.namedBindings;
                if (namedBindings && namedBindings.kind === 240 /* NamespaceImport */) {
                    handleNamespaceImportLike(namedBindings.name);
                    return;
                }
                if (exportKind === 0 /* Named */) {
                    searchForNamedImport(namedBindings);
                }
                else {
                    // `export =` might be imported by a default import if `--allowSyntheticDefaultImports` is on, so this handles both ExportKind.Default and ExportKind.ExportEquals
                    var name = importClause.name;
                    // If a default import has the same name as the default export, allow to rename it.
                    // Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that.
                    if (name && (!isForRename || name.escapedText === symbolName(exportSymbol))) {
                        var defaultImportAlias = checker.getSymbolAtLocation(name);
                        addSearch(name, defaultImportAlias);
                    }
                    // 'default' might be accessed as a named import `{ default as foo }`.
                    if (!isForRename && exportKind === 1 /* Default */) {
                        searchForNamedImport(namedBindings);
                    }
                }
            }
            /**
             * `import x = require("./x") or `import * as x from "./x"`.
             * An `export =` may be imported by this syntax, so it may be a direct import.
             * If it's not a direct import, it will be in `indirectUsers`, so we don't have to do anything here.
             */
            function handleNamespaceImportLike(importName) {
                // Don't rename an import that already has a different name than the export.
                if (exportKind === 2 /* ExportEquals */ && (!isForRename || isNameMatch(importName.escapedText))) {
                    addSearch(importName, checker.getSymbolAtLocation(importName));
                }
            }
            function searchForNamedImport(namedBindings) {
                if (!namedBindings) {
                    return;
                }
                for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    var name = element.name, propertyName = element.propertyName;
                    if (!isNameMatch((propertyName || name).escapedText)) {
                        continue;
                    }
                    if (propertyName) {
                        // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
                        singleReferences.push(propertyName);
                        if (!isForRename) {
                            // Search locally for `bar`.
                            addSearch(name, checker.getSymbolAtLocation(name));
                        }
                    }
                    else {
                        var localSymbol = element.kind === 246 /* ExportSpecifier */ && element.propertyName
                            ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol.
                            : checker.getSymbolAtLocation(name);
                        addSearch(name, localSymbol);
                    }
                }
            }
            function isNameMatch(name) {
                // Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
                return name === exportSymbol.escapedName || exportKind !== 0 /* Named */ && name === "default";
            }
        }
        /** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */
        function findNamespaceReExports(sourceFileLike, name, checker) {
            var namespaceImportSymbol = checker.getSymbolAtLocation(name);
            return forEachPossibleImportOrExportStatement(sourceFileLike, function (statement) {
                if (statement.kind !== 244 /* ExportDeclaration */)
                    return;
                var _a = statement, exportClause = _a.exportClause, moduleSpecifier = _a.moduleSpecifier;
                if (moduleSpecifier || !exportClause)
                    return;
                for (var _i = 0, _b = exportClause.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol) {
                        return true;
                    }
                }
            });
        }
        function findModuleReferences(program, sourceFiles, searchModuleSymbol) {
            var refs = [];
            var checker = program.getTypeChecker();
            for (var _i = 0, sourceFiles_4 = sourceFiles; _i < sourceFiles_4.length; _i++) {
                var referencingFile = sourceFiles_4[_i];
                var searchSourceFile = searchModuleSymbol.valueDeclaration;
                if (searchSourceFile.kind === 265 /* SourceFile */) {
                    for (var _a = 0, _b = referencingFile.referencedFiles; _a < _b.length; _a++) {
                        var ref = _b[_a];
                        if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) {
                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
                        }
                    }
                    for (var _c = 0, _d = referencingFile.typeReferenceDirectives; _c < _d.length; _c++) {
                        var ref = _d[_c];
                        var referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName);
                        if (referenced !== undefined && referenced.resolvedFileName === searchSourceFile.fileName) {
                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
                        }
                    }
                }
                forEachImport(referencingFile, function (_importDecl, moduleSpecifier) {
                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
                    if (moduleSymbol === searchModuleSymbol) {
                        refs.push({ kind: "import", literal: moduleSpecifier });
                    }
                });
            }
            return refs;
        }
        FindAllReferences.findModuleReferences = findModuleReferences;
        /** Returns a map from a module symbol Id to all import statements that directly reference the module. */
        function getDirectImportsMap(sourceFiles, checker, cancellationToken) {
            var map = ts.createMap();
            for (var _i = 0, sourceFiles_5 = sourceFiles; _i < sourceFiles_5.length; _i++) {
                var sourceFile = sourceFiles_5[_i];
                cancellationToken.throwIfCancellationRequested();
                forEachImport(sourceFile, function (importDecl, moduleSpecifier) {
                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
                    if (moduleSymbol) {
                        var id = ts.getSymbolId(moduleSymbol).toString();
                        var imports = map.get(id);
                        if (!imports) {
                            map.set(id, imports = []);
                        }
                        imports.push(importDecl);
                    }
                });
            }
            return map;
        }
        /** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */
        function forEachPossibleImportOrExportStatement(sourceFileLike, action) {
            return ts.forEach(sourceFileLike.kind === 265 /* SourceFile */ ? sourceFileLike.statements : sourceFileLike.body.statements, function (statement) {
                return action(statement) || (isAmbientModuleDeclaration(statement) && ts.forEach(statement.body && statement.body.statements, action));
            });
        }
        /** Calls `action` for each import, re-export, or require() in a file. */
        function forEachImport(sourceFile, action) {
            if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) {
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var moduleSpecifier = _a[_i];
                    action(importerFromModuleSpecifier(moduleSpecifier), moduleSpecifier);
                }
            }
            else {
                forEachPossibleImportOrExportStatement(sourceFile, function (statement) {
                    switch (statement.kind) {
                        case 244 /* ExportDeclaration */:
                        case 238 /* ImportDeclaration */: {
                            var decl = statement;
                            if (decl.moduleSpecifier && decl.moduleSpecifier.kind === 9 /* StringLiteral */) {
                                action(decl, decl.moduleSpecifier);
                            }
                            break;
                        }
                        case 237 /* ImportEqualsDeclaration */: {
                            var decl = statement;
                            var moduleReference = decl.moduleReference;
                            if (moduleReference.kind === 248 /* ExternalModuleReference */ &&
                                moduleReference.expression.kind === 9 /* StringLiteral */) {
                                action(decl, moduleReference.expression);
                            }
                            break;
                        }
                    }
                });
            }
        }
        function importerFromModuleSpecifier(moduleSpecifier) {
            var decl = moduleSpecifier.parent;
            switch (decl.kind) {
                case 181 /* CallExpression */:
                case 238 /* ImportDeclaration */:
                case 244 /* ExportDeclaration */:
                    return decl;
                case 248 /* ExternalModuleReference */:
                    return decl.parent;
                default:
                    ts.Debug.fail("Unexpected module specifier parent: " + decl.kind);
            }
        }
        /**
         * Given a local reference, we might notice that it's an import/export and recursively search for references of that.
         * If at an import, look locally for the symbol it imports.
         * If an an export, look for all imports of it.
         * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`.
         * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here.
         */
        function getImportOrExportSymbol(node, symbol, checker, comingFromExport) {
            return comingFromExport ? getExport() : getExport() || getImport();
            function getExport() {
                var parent = node.parent;
                if (symbol.exportSymbol) {
                    if (parent.kind === 179 /* PropertyAccessExpression */) {
                        // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use.
                        // So check that we are at the declaration.
                        return symbol.declarations.some(function (d) { return d === parent; }) && ts.isBinaryExpression(parent.parent)
                            ? getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ false)
                            : undefined;
                    }
                    else {
                        return exportInfo(symbol.exportSymbol, getExportKindForDeclaration(parent));
                    }
                }
                else {
                    var exportNode = getExportNode(parent, node);
                    if (exportNode && ts.hasModifier(exportNode, 1 /* Export */)) {
                        if (ts.isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) {
                            // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement.
                            if (comingFromExport) {
                                return undefined;
                            }
                            var lhsSymbol = checker.getSymbolAtLocation(exportNode.name);
                            return { kind: 0 /* Import */, symbol: lhsSymbol, isNamedImport: false };
                        }
                        else {
                            return exportInfo(symbol, getExportKindForDeclaration(exportNode));
                        }
                    }
                    else if (ts.isExportAssignment(parent)) {
                        return getExportAssignmentExport(parent);
                    }
                    else if (ts.isExportAssignment(parent.parent)) {
                        return getExportAssignmentExport(parent.parent);
                    }
                    else if (ts.isBinaryExpression(parent)) {
                        return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true);
                    }
                    else if (ts.isBinaryExpression(parent.parent)) {
                        return getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ true);
                    }
                }
                function getExportAssignmentExport(ex) {
                    // Get the symbol for the `export =` node; its parent is the module it's the export of.
                    var exportingModuleSymbol = ex.symbol.parent;
                    ts.Debug.assert(!!exportingModuleSymbol);
                    var exportKind = ex.isExportEquals ? 2 /* ExportEquals */ : 1 /* Default */;
                    return { kind: 1 /* Export */, symbol: symbol, exportInfo: { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } };
                }
                function getSpecialPropertyExport(node, useLhsSymbol) {
                    var kind;
                    switch (ts.getSpecialPropertyAssignmentKind(node)) {
                        case 1 /* ExportsProperty */:
                            kind = 0 /* Named */;
                            break;
                        case 2 /* ModuleExports */:
                            kind = 2 /* ExportEquals */;
                            break;
                        default:
                            return undefined;
                    }
                    var sym = useLhsSymbol ? checker.getSymbolAtLocation(node.left.name) : symbol;
                    return sym && exportInfo(sym, kind);
                }
            }
            function getImport() {
                var isImport = isNodeImport(node);
                if (!isImport)
                    return undefined;
                // A symbol being imported is always an alias. So get what that aliases to find the local symbol.
                var importedSymbol = checker.getImmediateAliasedSymbol(symbol);
                if (!importedSymbol)
                    return undefined;
                // Search on the local symbol in the exporting module, not the exported symbol.
                importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker);
                // Similarly, skip past the symbol for 'export ='
                if (importedSymbol.escapedName === "export=") {
                    importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
                }
                // If the import has a different name than the export, do not continue searching.
                // If `importedName` is undefined, do continue searching as the export is anonymous.
                // (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
                var importedName = symbolName(importedSymbol);
                if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) {
                    return __assign({ kind: 0 /* Import */, symbol: importedSymbol }, isImport);
                }
            }
            function exportInfo(symbol, kind) {
                var exportInfo = getExportInfo(symbol, kind, checker);
                return exportInfo && { kind: 1 /* Export */, symbol: symbol, exportInfo: exportInfo };
            }
            // Not meant for use with export specifiers or export assignment.
            function getExportKindForDeclaration(node) {
                return ts.hasModifier(node, 512 /* Default */) ? 1 /* Default */ : 0 /* Named */;
            }
        }
        FindAllReferences.getImportOrExportSymbol = getImportOrExportSymbol;
        function getExportEqualsLocalSymbol(importedSymbol, checker) {
            if (importedSymbol.flags & 2097152 /* Alias */) {
                return checker.getImmediateAliasedSymbol(importedSymbol);
            }
            var decl = importedSymbol.valueDeclaration;
            if (ts.isExportAssignment(decl)) {
                return decl.expression.symbol;
            }
            else if (ts.isBinaryExpression(decl)) {
                return decl.right.symbol;
            }
            ts.Debug.fail();
        }
        // If a reference is a class expression, the exported node would be its parent.
        // If a reference is a variable declaration, the exported node would be the variable statement.
        function getExportNode(parent, node) {
            if (parent.kind === 226 /* VariableDeclaration */) {
                var p = parent;
                return p.name !== node ? undefined :
                    p.parent.kind === 260 /* CatchClause */ ? undefined : p.parent.parent.kind === 208 /* VariableStatement */ ? p.parent.parent : undefined;
            }
            else {
                return parent;
            }
        }
        function isNodeImport(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 237 /* ImportEqualsDeclaration */:
                    return parent.name === node && isExternalModuleImportEquals(parent)
                        ? { isNamedImport: false }
                        : undefined;
                case 242 /* ImportSpecifier */:
                    // For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`.
                    return parent.propertyName ? undefined : { isNamedImport: true };
                case 239 /* ImportClause */:
                case 240 /* NamespaceImport */:
                    ts.Debug.assert(parent.name === node);
                    return { isNamedImport: false };
                default:
                    return undefined;
            }
        }
        function getExportInfo(exportSymbol, exportKind, checker) {
            var exportingModuleSymbol = checker.getMergedSymbol(exportSymbol.parent); // Need to get merged symbol in case there's an augmentation.
            // `export` may appear in a namespace. In that case, just rely on global search.
            return ts.isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } : undefined;
        }
        FindAllReferences.getExportInfo = getExportInfo;
        function symbolName(symbol) {
            if (symbol.escapedName !== "default") {
                return symbol.escapedName;
            }
            return ts.forEach(symbol.declarations, function (decl) {
                var name = ts.getNameOfDeclaration(decl);
                return name && name.kind === 71 /* Identifier */ && name.escapedText;
            });
        }
        /** If at an export specifier, go to the symbol it refers to. */
        function skipExportSpecifierSymbol(symbol, checker) {
            // For `export { foo } from './bar", there's nothing to skip, because it does  not create a new alias. But `export { foo } does.
            if (symbol.declarations) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (ts.isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) {
                        return checker.getExportSpecifierLocalTargetSymbol(declaration);
                    }
                }
            }
            return symbol;
        }
        function getContainingModuleSymbol(importer, checker) {
            return checker.getMergedSymbol(getSourceFileLikeForImportDeclaration(importer).symbol);
        }
        function getSourceFileLikeForImportDeclaration(node) {
            if (node.kind === 181 /* CallExpression */) {
                return node.getSourceFile();
            }
            var parent = node.parent;
            if (parent.kind === 265 /* SourceFile */) {
                return parent;
            }
            ts.Debug.assert(parent.kind === 234 /* ModuleBlock */ && isAmbientModuleDeclaration(parent.parent));
            return parent.parent;
        }
        function isAmbientModuleDeclaration(node) {
            return node.kind === 233 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */;
        }
        function isExternalModuleImportEquals(_a) {
            var moduleReference = _a.moduleReference;
            return moduleReference.kind === 248 /* ExternalModuleReference */ && moduleReference.expression.kind === 9 /* StringLiteral */;
        }
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/// <reference path="./importTracker.ts" />
/* @internal */
var ts;
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        function nodeEntry(node, isInString) {
            return { type: "node", node: node, isInString: isInString };
        }
        FindAllReferences.nodeEntry = nodeEntry;
        function findReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position) {
            var referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
            if (!referencedSymbols || !referencedSymbols.length) {
                return undefined;
            }
            var out = [];
            var checker = program.getTypeChecker();
            for (var _i = 0, referencedSymbols_1 = referencedSymbols; _i < referencedSymbols_1.length; _i++) {
                var _a = referencedSymbols_1[_i], definition = _a.definition, references = _a.references;
                // Only include referenced symbols that have a valid definition.
                if (definition) {
                    out.push({ definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
                }
            }
            return out;
        }
        FindAllReferences.findReferencedSymbols = findReferencedSymbols;
        function getImplementationsAtPosition(program, cancellationToken, sourceFiles, sourceFile, position) {
            // A node in a JSDoc comment can't have an implementation anyway.
            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false);
            var referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node);
            var checker = program.getTypeChecker();
            return ts.map(referenceEntries, function (entry) { return toImplementationLocation(entry, checker); });
        }
        FindAllReferences.getImplementationsAtPosition = getImplementationsAtPosition;
        function getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node) {
            if (node.kind === 265 /* SourceFile */) {
                return undefined;
            }
            var checker = program.getTypeChecker();
            // If invoked directly on a shorthand property assignment, then return
            // the declaration of the symbol being assigned (not the symbol being assigned to).
            if (node.parent.kind === 262 /* ShorthandPropertyAssignment */) {
                var result_5 = [];
                FindAllReferences.Core.getReferenceEntriesForShorthandPropertyAssignment(node, checker, function (node) { return result_5.push(nodeEntry(node)); });
                return result_5;
            }
            else if (node.kind === 97 /* SuperKeyword */ || ts.isSuperProperty(node.parent)) {
                // References to and accesses on the super keyword only have one possible implementation, so no
                // need to "Find all References"
                var symbol = checker.getSymbolAtLocation(node);
                return symbol.valueDeclaration && [nodeEntry(symbol.valueDeclaration)];
            }
            else {
                // Perform "Find all References" and retrieve only those that are implementations
                return getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, { implementations: true });
            }
        }
        function findReferencedEntries(program, cancellationToken, sourceFiles, sourceFile, position, options) {
            var x = flattenEntries(findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options));
            return ts.map(x, toReferenceEntry);
        }
        FindAllReferences.findReferencedEntries = findReferencedEntries;
        function getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, options) {
            if (options === void 0) { options = {}; }
            return flattenEntries(FindAllReferences.Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options));
        }
        FindAllReferences.getReferenceEntriesForNode = getReferenceEntriesForNode;
        function findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options) {
            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
            return FindAllReferences.Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options);
        }
        function flattenEntries(referenceSymbols) {
            return referenceSymbols && ts.flatMap(referenceSymbols, function (r) { return r.references; });
        }
        function definitionToReferencedSymbolDefinitionInfo(def, checker) {
            var info = (function () {
                switch (def.type) {
                    case "symbol": {
                        var symbol = def.symbol, node_2 = def.node;
                        var _a = getDefinitionKindAndDisplayParts(symbol, node_2, checker), displayParts_1 = _a.displayParts, kind_1 = _a.kind;
                        var name_4 = displayParts_1.map(function (p) { return p.text; }).join("");
                        return { node: node_2, name: name_4, kind: kind_1, displayParts: displayParts_1 };
                    }
                    case "label": {
                        var node_3 = def.node;
                        return { node: node_3, name: node_3.text, kind: "label" /* label */, displayParts: [ts.displayPart(node_3.text, ts.SymbolDisplayPartKind.text)] };
                    }
                    case "keyword": {
                        var node_4 = def.node;
                        var name_5 = ts.tokenToString(node_4.kind);
                        return { node: node_4, name: name_5, kind: "keyword" /* keyword */, displayParts: [{ text: name_5, kind: "keyword" /* keyword */ }] };
                    }
                    case "this": {
                        var node_5 = def.node;
                        var symbol = checker.getSymbolAtLocation(node_5);
                        var displayParts_2 = symbol && ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node_5.getSourceFile(), ts.getContainerNode(node_5), node_5).displayParts;
                        return { node: node_5, name: "this", kind: "var" /* variableElement */, displayParts: displayParts_2 };
                    }
                    case "string": {
                        var node_6 = def.node;
                        return { node: node_6, name: node_6.text, kind: "var" /* variableElement */, displayParts: [ts.displayPart(ts.getTextOfNode(node_6), ts.SymbolDisplayPartKind.stringLiteral)] };
                    }
                }
            })();
            if (!info) {
                return undefined;
            }
            var node = info.node, name = info.name, kind = info.kind, displayParts = info.displayParts;
            var sourceFile = node.getSourceFile();
            return {
                containerKind: "" /* unknown */,
                containerName: "",
                fileName: sourceFile.fileName,
                kind: kind,
                name: name,
                textSpan: ts.createTextSpanFromNode(node, sourceFile),
                displayParts: displayParts
            };
        }
        function getDefinitionKindAndDisplayParts(symbol, node, checker) {
            var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node.getSourceFile(), ts.getContainerNode(node), node), displayParts = _a.displayParts, symbolKind = _a.symbolKind;
            return { displayParts: displayParts, kind: symbolKind };
        }
        function toReferenceEntry(entry) {
            if (entry.type === "span") {
                return { textSpan: entry.textSpan, fileName: entry.fileName, isWriteAccess: false, isDefinition: false };
            }
            var node = entry.node, isInString = entry.isInString;
            return {
                fileName: node.getSourceFile().fileName,
                textSpan: getTextSpan(node),
                isWriteAccess: isWriteAccessForReference(node),
                isDefinition: node.kind === 79 /* DefaultKeyword */
                    || ts.isAnyDeclarationName(node)
                    || ts.isLiteralComputedPropertyDeclarationName(node),
                isInString: isInString
            };
        }
        function toImplementationLocation(entry, checker) {
            if (entry.type === "node") {
                var node = entry.node;
                return __assign({ textSpan: getTextSpan(node), fileName: node.getSourceFile().fileName }, implementationKindDisplayParts(node, checker));
            }
            else {
                var textSpan = entry.textSpan, fileName = entry.fileName;
                return { textSpan: textSpan, fileName: fileName, kind: "" /* unknown */, displayParts: [] };
            }
        }
        function implementationKindDisplayParts(node, checker) {
            var symbol = checker.getSymbolAtLocation(ts.isDeclaration(node) && node.name ? node.name : node);
            if (symbol) {
                return getDefinitionKindAndDisplayParts(symbol, node, checker);
            }
            else if (node.kind === 178 /* ObjectLiteralExpression */) {
                return {
                    kind: "interface" /* interfaceElement */,
                    displayParts: [ts.punctuationPart(19 /* OpenParenToken */), ts.textPart("object literal"), ts.punctuationPart(20 /* CloseParenToken */)]
                };
            }
            else if (node.kind === 199 /* ClassExpression */) {
                return {
                    kind: "local class" /* localClassElement */,
                    displayParts: [ts.punctuationPart(19 /* OpenParenToken */), ts.textPart("anonymous local class"), ts.punctuationPart(20 /* CloseParenToken */)]
                };
            }
            else {
                return { kind: ts.getNodeKind(node), displayParts: [] };
            }
        }
        function toHighlightSpan(entry) {
            if (entry.type === "span") {
                var fileName_1 = entry.fileName, textSpan = entry.textSpan;
                return { fileName: fileName_1, span: { textSpan: textSpan, kind: "reference" /* reference */ } };
            }
            var node = entry.node, isInString = entry.isInString;
            var fileName = entry.node.getSourceFile().fileName;
            var writeAccess = isWriteAccessForReference(node);
            var span = {
                textSpan: getTextSpan(node),
                kind: writeAccess ? "writtenReference" /* writtenReference */ : "reference" /* reference */,
                isInString: isInString
            };
            return { fileName: fileName, span: span };
        }
        FindAllReferences.toHighlightSpan = toHighlightSpan;
        function getTextSpan(node) {
            var start = node.getStart();
            var end = node.getEnd();
            if (node.kind === 9 /* StringLiteral */) {
                start += 1;
                end -= 1;
            }
            return ts.createTextSpanFromBounds(start, end);
        }
        /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
        function isWriteAccessForReference(node) {
            return node.kind === 79 /* DefaultKeyword */ || ts.isAnyDeclarationName(node) || ts.isWriteAccess(node);
        }
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/** Encapsulates the core find-all-references algorithm. */
/* @internal */
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        var Core;
        (function (Core) {
            /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */
            function getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options) {
                if (options === void 0) { options = {}; }
                if (node.kind === 265 /* SourceFile */) {
                    return undefined;
                }
                if (!options.implementations) {
                    var special = getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken);
                    if (special) {
                        return special;
                    }
                }
                var checker = program.getTypeChecker();
                var symbol = checker.getSymbolAtLocation(node);
                // Could not find a symbol e.g. unknown identifier
                if (!symbol) {
                    // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial.
                    if (!options.implementations && node.kind === 9 /* StringLiteral */) {
                        return getReferencesForStringLiteral(node, sourceFiles, cancellationToken);
                    }
                    // Can't have references to something that we have no symbol for.
                    return undefined;
                }
                if (symbol.flags & 1536 /* Module */ && isModuleReferenceLocation(node)) {
                    return getReferencedSymbolsForModule(program, symbol, sourceFiles);
                }
                return getReferencedSymbolsForSymbol(symbol, node, sourceFiles, checker, cancellationToken, options);
            }
            Core.getReferencedSymbolsForNode = getReferencedSymbolsForNode;
            function isModuleReferenceLocation(node) {
                if (node.kind !== 9 /* StringLiteral */) {
                    return false;
                }
                switch (node.parent.kind) {
                    case 233 /* ModuleDeclaration */:
                    case 248 /* ExternalModuleReference */:
                    case 238 /* ImportDeclaration */:
                    case 244 /* ExportDeclaration */:
                        return true;
                    case 181 /* CallExpression */:
                        return ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || ts.isImportCall(node.parent);
                    default:
                        return false;
                }
            }
            function getReferencedSymbolsForModule(program, symbol, sourceFiles) {
                ts.Debug.assert(!!symbol.valueDeclaration);
                var references = FindAllReferences.findModuleReferences(program, sourceFiles, symbol).map(function (reference) {
                    if (reference.kind === "import") {
                        return { type: "node", node: reference.literal };
                    }
                    else {
                        return {
                            type: "span",
                            fileName: reference.referencingFile.fileName,
                            textSpan: ts.createTextSpanFromRange(reference.ref),
                        };
                    }
                });
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    switch (decl.kind) {
                        case 265 /* SourceFile */:
                            // Don't include the source file itself. (This may not be ideal behavior, but awkward to include an entire file as a reference.)
                            break;
                        case 233 /* ModuleDeclaration */:
                            references.push({ type: "node", node: decl.name });
                            break;
                        default:
                            ts.Debug.fail("Expected a module symbol to be declared by a SourceFile or ModuleDeclaration.");
                    }
                }
                return [{
                        definition: { type: "symbol", symbol: symbol, node: symbol.valueDeclaration },
                        references: references
                    }];
            }
            /** getReferencedSymbols for special node kinds. */
            function getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken) {
                if (ts.isTypeKeyword(node.kind)) {
                    return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken);
                }
                // Labels
                if (ts.isLabelName(node)) {
                    if (ts.isJumpStatementTarget(node)) {
                        var labelDefinition = ts.getTargetLabel(node.parent, node.text);
                        // if we have a label definition, look within its statement for references, if not, then
                        // the label is undefined and we have no results..
                        return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition);
                    }
                    else {
                        // it is a label definition and not a target, search within the parent labeledStatement
                        return getLabelReferencesInNode(node.parent, node);
                    }
                }
                if (ts.isThis(node)) {
                    return getReferencesForThisKeyword(node, sourceFiles, cancellationToken);
                }
                if (node.kind === 97 /* SuperKeyword */) {
                    return getReferencesForSuperKeyword(node);
                }
                return undefined;
            }
            /** Core find-all-references algorithm for a normal symbol. */
            function getReferencedSymbolsForSymbol(symbol, node, sourceFiles, checker, cancellationToken, options) {
                symbol = skipPastExportOrImportSpecifier(symbol, node, checker);
                // Compute the meaning from the location and the symbol it references
                var searchMeaning = getIntersectingMeaningFromDeclarations(ts.getMeaningFromLocation(node), symbol.declarations);
                var result = [];
                var state = new State(sourceFiles, /*isForConstructor*/ node.kind === 123 /* ConstructorKeyword */, checker, cancellationToken, searchMeaning, options, result);
                if (node.kind === 79 /* DefaultKeyword */) {
                    addReference(node, symbol, node, state);
                    searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: 1 /* Default */ }, state);
                }
                else {
                    var search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) });
                    // Try to get the smallest valid scope that we can limit our search to;
                    // otherwise we'll need to search globally (i.e. include each file).
                    var scope = getSymbolScope(symbol);
                    if (scope) {
                        getReferencesInContainer(scope, scope.getSourceFile(), search, state);
                    }
                    else {
                        // Global search
                        for (var _i = 0, _a = state.sourceFiles; _i < _a.length; _i++) {
                            var sourceFile = _a[_i];
                            state.cancellationToken.throwIfCancellationRequested();
                            searchForName(sourceFile, search, state);
                        }
                    }
                }
                return result;
            }
            /** Handle a few special cases relating to export/import specifiers. */
            function skipPastExportOrImportSpecifier(symbol, node, checker) {
                var parent = node.parent;
                if (ts.isExportSpecifier(parent)) {
                    return getLocalSymbolForExportSpecifier(node, symbol, parent, checker);
                }
                if (ts.isImportSpecifier(parent) && parent.propertyName === node) {
                    // We're at `foo` in `import { foo as bar }`. Probably intended to find all refs on the original, not just on the import.
                    return checker.getImmediateAliasedSymbol(symbol);
                }
                return symbol;
            }
            /**
             * Holds all state needed for the finding references.
             * Unlike `Search`, there is only one `State`.
             */
            var State = /** @class */ (function () {
                function State(sourceFiles, 
                    /** True if we're searching for constructor references. */
                    isForConstructor, checker, cancellationToken, searchMeaning, options, result) {
                    this.sourceFiles = sourceFiles;
                    this.isForConstructor = isForConstructor;
                    this.checker = checker;
                    this.cancellationToken = cancellationToken;
                    this.searchMeaning = searchMeaning;
                    this.options = options;
                    this.result = result;
                    /** Cache for `explicitlyinheritsFrom`. */
                    this.inheritsFromCache = ts.createMap();
                    /**
                     * Type nodes can contain multiple references to the same type. For example:
                     *      let x: Foo & (Foo & Bar) = ...
                     * Because we are returning the implementation locations and not the identifier locations,
                     * duplicate entries would be returned here as each of the type references is part of
                     * the same implementation. For that reason, check before we add a new entry.
                     */
                    this.markSeenContainingTypeReference = ts.nodeSeenTracker();
                    /**
                     * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once.
                     * For example:
                     *     // b.ts
                     *     export { foo as bar } from "./a";
                     *     import { bar } from "./b";
                     *
                     * Normally at `foo as bar` we directly add `foo` and do not locally search for it (since it doesn't declare a local).
                     * But another reference to it may appear in the same source file.
                     * See `tests/cases/fourslash/transitiveExportImports3.ts`.
                     */
                    this.markSeenReExportRHS = ts.nodeSeenTracker();
                    this.symbolIdToReferences = [];
                    // Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
                    this.sourceFileToSeenSymbols = [];
                }
                /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
                State.prototype.getImportSearches = function (exportSymbol, exportInfo) {
                    if (!this.importTracker)
                        this.importTracker = FindAllReferences.createImportTracker(this.sourceFiles, this.checker, this.cancellationToken);
                    return this.importTracker(exportSymbol, exportInfo, this.options.isForRename);
                };
                /** @param allSearchSymbols set of additinal symbols for use by `includes`. */
                State.prototype.createSearch = function (location, symbol, comingFrom, searchOptions) {
                    if (searchOptions === void 0) { searchOptions = {}; }
                    // Note: if this is an external module symbol, the name doesn't include quotes.
                    var _a = searchOptions.text, text = _a === void 0 ? ts.stripQuotes(ts.unescapeLeadingUnderscores((ts.getLocalSymbolForExportDefault(symbol) || symbol).escapedName)) : _a, _b = searchOptions.allSearchSymbols, allSearchSymbols = _b === void 0 ? undefined : _b;
                    var escapedText = ts.escapeLeadingUnderscores(text);
                    var parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker);
                    return {
                        location: location, symbol: symbol, comingFrom: comingFrom, text: text, escapedText: escapedText, parents: parents,
                        includes: function (referenceSymbol) { return allSearchSymbols ? ts.contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol; },
                    };
                };
                /**
                 * Callback to add references for a particular searched symbol.
                 * This initializes a reference group, so only call this if you will add at least one reference.
                 */
                State.prototype.referenceAdder = function (searchSymbol, searchLocation) {
                    var symbolId = ts.getSymbolId(searchSymbol);
                    var references = this.symbolIdToReferences[symbolId];
                    if (!references) {
                        references = this.symbolIdToReferences[symbolId] = [];
                        this.result.push({ definition: { type: "symbol", symbol: searchSymbol, node: searchLocation }, references: references });
                    }
                    return function (node) { return references.push(FindAllReferences.nodeEntry(node)); };
                };
                /** Add a reference with no associated definition. */
                State.prototype.addStringOrCommentReference = function (fileName, textSpan) {
                    this.result.push({
                        definition: undefined,
                        references: [{ type: "span", fileName: fileName, textSpan: textSpan }]
                    });
                };
                /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
                State.prototype.markSearchedSymbol = function (sourceFile, symbol) {
                    var sourceId = ts.getNodeId(sourceFile);
                    var symbolId = ts.getSymbolId(symbol);
                    var seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = []);
                    return !seenSymbols[symbolId] && (seenSymbols[symbolId] = true);
                };
                return State;
            }());
            /** Search for all imports of a given exported symbol using `State.getImportSearches`. */
            function searchForImportsOfExport(exportLocation, exportSymbol, exportInfo, state) {
                var _a = state.getImportSearches(exportSymbol, exportInfo), importSearches = _a.importSearches, singleReferences = _a.singleReferences, indirectUsers = _a.indirectUsers;
                // For `import { foo as bar }` just add the reference to `foo`, and don't otherwise search in the file.
                if (singleReferences.length) {
                    var addRef = state.referenceAdder(exportSymbol, exportLocation);
                    for (var _i = 0, singleReferences_1 = singleReferences; _i < singleReferences_1.length; _i++) {
                        var singleRef = singleReferences_1[_i];
                        addRef(singleRef);
                    }
                }
                // For each import, find all references to that import in its source file.
                for (var _b = 0, importSearches_1 = importSearches; _b < importSearches_1.length; _b++) {
                    var _c = importSearches_1[_b], importLocation = _c[0], importSymbol = _c[1];
                    getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, 1 /* Export */), state);
                }
                if (indirectUsers.length) {
                    var indirectSearch = void 0;
                    switch (exportInfo.exportKind) {
                        case 0 /* Named */:
                            indirectSearch = state.createSearch(exportLocation, exportSymbol, 1 /* Export */);
                            break;
                        case 1 /* Default */:
                            // Search for a property access to '.default'. This can't be renamed.
                            indirectSearch = state.options.isForRename ? undefined : state.createSearch(exportLocation, exportSymbol, 1 /* Export */, { text: "default" });
                            break;
                        case 2 /* ExportEquals */:
                            break;
                    }
                    if (indirectSearch) {
                        for (var _d = 0, indirectUsers_1 = indirectUsers; _d < indirectUsers_1.length; _d++) {
                            var indirectUser = indirectUsers_1[_d];
                            searchForName(indirectUser, indirectSearch, state);
                        }
                    }
                }
            }
            // Go to the symbol we imported from and find references for it.
            function searchForImportedSymbol(symbol, state) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    getReferencesInSourceFile(declaration.getSourceFile(), state.createSearch(declaration, symbol, 0 /* Import */), state);
                }
            }
            /** Search for all occurences of an identifier in a source file (and filter out the ones that match). */
            function searchForName(sourceFile, search, state) {
                if (ts.getNameTable(sourceFile).get(search.escapedText) !== undefined) {
                    getReferencesInSourceFile(sourceFile, search, state);
                }
            }
            function getPropertySymbolOfDestructuringAssignment(location, checker) {
                return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) &&
                    checker.getPropertySymbolOfDestructuringAssignment(location);
            }
            function getObjectBindingElementWithoutPropertyName(symbol) {
                var bindingElement = ts.getDeclarationOfKind(symbol, 176 /* BindingElement */);
                if (bindingElement &&
                    bindingElement.parent.kind === 174 /* ObjectBindingPattern */ &&
                    !bindingElement.propertyName) {
                    return bindingElement;
                }
            }
            function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) {
                var bindingElement = getObjectBindingElementWithoutPropertyName(symbol);
                if (!bindingElement)
                    return undefined;
                var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
                var propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
                if (propSymbol && propSymbol.flags & 98304 /* Accessor */) {
                    // See GH#16922
                    ts.Debug.assert(!!(propSymbol.flags & 33554432 /* Transient */));
                    return propSymbol.target;
                }
                return propSymbol;
            }
            /**
             * Determines the smallest scope in which a symbol may have named references.
             * Note that not every construct has been accounted for. This function can
             * probably be improved.
             *
             * @returns undefined if the scope cannot be determined, implying that
             * a reference to a symbol can occur anywhere.
             */
            function getSymbolScope(symbol) {
                // If this is the symbol of a named function expression or named class expression,
                // then named references are limited to its own scope.
                var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration;
                if (valueDeclaration && (valueDeclaration.kind === 186 /* FunctionExpression */ || valueDeclaration.kind === 199 /* ClassExpression */)) {
                    return valueDeclaration;
                }
                if (!declarations) {
                    return undefined;
                }
                // If this is private property or method, the scope is the containing class
                if (flags & (4 /* Property */ | 8192 /* Method */)) {
                    var privateDeclaration = ts.find(declarations, function (d) { return ts.hasModifier(d, 8 /* Private */); });
                    if (privateDeclaration) {
                        return ts.getAncestor(privateDeclaration, 229 /* ClassDeclaration */);
                    }
                    // Else this is a public property and could be accessed from anywhere.
                    return undefined;
                }
                // If symbol is of object binding pattern element without property name we would want to
                // look for property too and that could be anywhere
                if (getObjectBindingElementWithoutPropertyName(symbol)) {
                    return undefined;
                }
                /*
                If the symbol has a parent, it's globally visible unless:
                - It's a private property (handled above).
                - It's a type parameter.
                - The parent is an external module: then we should only search in the module (and recurse on the export later).
                  - But if the parent has `export as namespace`, the symbol is globally visible through that namespace.
                */
                var exposedByParent = parent && !(symbol.flags & 262144 /* TypeParameter */);
                if (exposedByParent && !((parent.flags & 1536 /* Module */) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) {
                    return undefined;
                }
                var scope;
                for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) {
                    var declaration = declarations_9[_i];
                    var container = ts.getContainerNode(declaration);
                    if (scope && scope !== container) {
                        // Different declarations have different containers, bail out
                        return undefined;
                    }
                    if (!container || container.kind === 265 /* SourceFile */ && !ts.isExternalOrCommonJsModule(container)) {
                        // This is a global variable and not an external module, any declaration defined
                        // within this scope is visible outside the file
                        return undefined;
                    }
                    // The search scope is the container node
                    scope = container;
                }
                // If symbol.parent, this means we are in an export of an external module. (Otherwise we would have returned `undefined` above.)
                // For an export of a module, we may be in a declaration file, and it may be accessed elsewhere. E.g.:
                //     declare module "a" { export type T = number; }
                //     declare module "b" { import { T } from "a"; export const x: T; }
                // So we must search the whole source file. (Because we will mark the source file as seen, we we won't return to it when searching for imports.)
                return exposedByParent ? scope.getSourceFile() : scope;
            }
            function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) {
                if (container === void 0) { container = sourceFile; }
                var positions = [];
                /// TODO: Cache symbol existence for files to save text search
                // Also, need to make this work for unicode escapes.
                // Be resilient in the face of a symbol with no name or zero length name
                if (!symbolName || !symbolName.length) {
                    return positions;
                }
                var text = sourceFile.text;
                var sourceLength = text.length;
                var symbolNameLength = symbolName.length;
                var position = text.indexOf(symbolName, container.pos);
                while (position >= 0) {
                    // If we are past the end, stop looking
                    if (position > container.end)
                        break;
                    // We found a match.  Make sure it's not part of a larger word (i.e. the char
                    // before and after it have to be a non-identifier char).
                    var endPosition = position + symbolNameLength;
                    if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), 5 /* Latest */)) &&
                        (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 5 /* Latest */))) {
                        // Found a real match.  Keep searching.
                        positions.push(position);
                    }
                    position = text.indexOf(symbolName, position + symbolNameLength + 1);
                }
                return positions;
            }
            function getLabelReferencesInNode(container, targetLabel) {
                var references = [];
                var sourceFile = container.getSourceFile();
                var labelName = targetLabel.text;
                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container);
                for (var _i = 0, possiblePositions_1 = possiblePositions; _i < possiblePositions_1.length; _i++) {
                    var position = possiblePositions_1[_i];
                    var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
                    // Only pick labels that are either the target label, or have a target that is the target label
                    if (node && (node === targetLabel || (ts.isJumpStatementTarget(node) && ts.getTargetLabel(node, labelName) === targetLabel))) {
                        references.push(FindAllReferences.nodeEntry(node));
                    }
                }
                return [{ definition: { type: "label", node: targetLabel }, references: references }];
            }
            function isValidReferencePosition(node, searchSymbolName) {
                // Compare the length so we filter out strict superstrings of the symbol we are looking for
                switch (node.kind) {
                    case 71 /* Identifier */:
                        return node.text.length === searchSymbolName.length;
                    case 9 /* StringLiteral */:
                        return (ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&
                            node.text.length === searchSymbolName.length;
                    case 8 /* NumericLiteral */:
                        return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.text.length === searchSymbolName.length;
                    case 79 /* DefaultKeyword */:
                        return "default".length === searchSymbolName.length;
                    default:
                        return false;
                }
            }
            function getAllReferencesForKeyword(sourceFiles, keywordKind, cancellationToken) {
                var references = [];
                for (var _i = 0, sourceFiles_6 = sourceFiles; _i < sourceFiles_6.length; _i++) {
                    var sourceFile = sourceFiles_6[_i];
                    cancellationToken.throwIfCancellationRequested();
                    addReferencesForKeywordInFile(sourceFile, keywordKind, ts.tokenToString(keywordKind), references);
                }
                return references.length ? [{ definition: { type: "keyword", node: references[0].node }, references: references }] : undefined;
            }
            function addReferencesForKeywordInFile(sourceFile, kind, searchText, references) {
                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile);
                for (var _i = 0, possiblePositions_2 = possiblePositions; _i < possiblePositions_2.length; _i++) {
                    var position = possiblePositions_2[_i];
                    var referenceLocation = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
                    if (referenceLocation.kind === kind) {
                        references.push(FindAllReferences.nodeEntry(referenceLocation));
                    }
                }
            }
            function getReferencesInSourceFile(sourceFile, search, state) {
                state.cancellationToken.throwIfCancellationRequested();
                return getReferencesInContainer(sourceFile, sourceFile, search, state);
            }
            /**
             * Search within node "container" for references for a search value, where the search value is defined as a
             * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning).
             * searchLocation: a node where the search value
             */
            function getReferencesInContainer(container, sourceFile, search, state) {
                if (!state.markSearchedSymbol(sourceFile, search.symbol)) {
                    return;
                }
                for (var _i = 0, _a = getPossibleSymbolReferencePositions(sourceFile, search.text, container); _i < _a.length; _i++) {
                    var position = _a[_i];
                    getReferencesAtLocation(sourceFile, position, search, state);
                }
            }
            function getReferencesAtLocation(sourceFile, position, search, state) {
                var referenceLocation = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
                if (!isValidReferencePosition(referenceLocation, search.text)) {
                    // This wasn't the start of a token.  Check to see if it might be a
                    // match in a comment or string if that's what the caller is asking
                    // for.
                    if (!state.options.implementations && (state.options.findInStrings && ts.isInString(sourceFile, position) || state.options.findInComments && ts.isInNonReferenceComment(sourceFile, position))) {
                        // In the case where we're looking inside comments/strings, we don't have
                        // an actual definition.  So just use 'undefined' here.  Features like
                        // 'Rename' won't care (as they ignore the definitions), and features like
                        // 'FindReferences' will just filter out these results.
                        state.addStringOrCommentReference(sourceFile.fileName, ts.createTextSpan(position, search.text.length));
                    }
                    return;
                }
                if (!(ts.getMeaningFromLocation(referenceLocation) & state.searchMeaning)) {
                    return;
                }
                var referenceSymbol = state.checker.getSymbolAtLocation(referenceLocation);
                if (!referenceSymbol) {
                    return;
                }
                var parent = referenceLocation.parent;
                if (ts.isImportSpecifier(parent) && parent.propertyName === referenceLocation) {
                    // This is added through `singleReferences` in ImportsResult. If we happen to see it again, don't add it again.
                    return;
                }
                if (ts.isExportSpecifier(parent)) {
                    ts.Debug.assert(referenceLocation.kind === 71 /* Identifier */);
                    getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, parent, search, state);
                    return;
                }
                var relatedSymbol = getRelatedSymbol(search, referenceSymbol, referenceLocation, state);
                if (!relatedSymbol) {
                    getReferenceForShorthandProperty(referenceSymbol, search, state);
                    return;
                }
                if (state.isForConstructor) {
                    findConstructorReferences(referenceLocation, sourceFile, search, state);
                }
                else {
                    addReference(referenceLocation, relatedSymbol, search.location, state);
                }
                getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
            }
            function getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, search, state) {
                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
                var exportDeclaration = parent.parent;
                var localSymbol = getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, state.checker);
                if (!search.includes(localSymbol)) {
                    return;
                }
                if (!propertyName) {
                    addRef();
                }
                else if (referenceLocation === propertyName) {
                    // For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export.
                    // For `export { foo as bar };`, where `foo` is a local, so add it now.
                    if (!exportDeclaration.moduleSpecifier) {
                        addRef();
                    }
                    if (!state.options.isForRename && state.markSeenReExportRHS(name)) {
                        addReference(name, referenceSymbol, name, state);
                    }
                }
                else {
                    if (state.markSeenReExportRHS(referenceLocation)) {
                        addRef();
                    }
                }
                // For `export { foo as bar }`, rename `foo`, but not `bar`.
                if (!(referenceLocation === propertyName && state.options.isForRename)) {
                    var exportKind = referenceLocation.originalKeywordKind === 79 /* DefaultKeyword */ ? 1 /* Default */ : 0 /* Named */;
                    var exportInfo = FindAllReferences.getExportInfo(referenceSymbol, exportKind, state.checker);
                    ts.Debug.assert(!!exportInfo);
                    searchForImportsOfExport(referenceLocation, referenceSymbol, exportInfo, state);
                }
                // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`.
                if (search.comingFrom !== 1 /* Export */ && exportDeclaration.moduleSpecifier && !propertyName) {
                    searchForImportedSymbol(state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier), state);
                }
                function addRef() {
                    addReference(referenceLocation, localSymbol, search.location, state);
                }
            }
            function getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, checker) {
                return isExportSpecifierAlias(referenceLocation, exportSpecifier) ? checker.getExportSpecifierLocalTargetSymbol(exportSpecifier) : referenceSymbol;
            }
            function isExportSpecifierAlias(referenceLocation, exportSpecifier) {
                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
                ts.Debug.assert(propertyName === referenceLocation || name === referenceLocation);
                if (propertyName) {
                    // Given `export { foo as bar } [from "someModule"]`: It's an alias at `foo`, but at `bar` it's a new symbol.
                    return propertyName === referenceLocation;
                }
                else {
                    // `export { foo } from "foo"` is a re-export.
                    // `export { foo };` is not a re-export, it creates an alias for the local variable `foo`.
                    return !parent.parent.moduleSpecifier;
                }
            }
            function getImportOrExportReferences(referenceLocation, referenceSymbol, search, state) {
                var importOrExport = FindAllReferences.getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === 1 /* Export */);
                if (!importOrExport)
                    return;
                var symbol = importOrExport.symbol;
                if (importOrExport.kind === 0 /* Import */) {
                    if (!state.options.isForRename || importOrExport.isNamedImport) {
                        searchForImportedSymbol(symbol, state);
                    }
                }
                else {
                    // We don't check for `state.isForRename`, even for default exports, because importers that previously matched the export name should be updated to continue matching.
                    searchForImportsOfExport(referenceLocation, symbol, importOrExport.exportInfo, state);
                }
            }
            function getReferenceForShorthandProperty(_a, search, state) {
                var flags = _a.flags, valueDeclaration = _a.valueDeclaration;
                var shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration);
                /*
                 * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment
                 * has two meanings: property name and property value. Therefore when we do findAllReference at the position where
                 * an identifier is declared, the language service should return the position of the variable declaration as well as
                 * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the
                 * position of property accessing, the referenceEntry of such position will be handled in the first case.
                 */
                if (!(flags & 33554432 /* Transient */) && search.includes(shorthandValueSymbol)) {
                    addReference(ts.getNameOfDeclaration(valueDeclaration), shorthandValueSymbol, search.location, state);
                }
            }
            function addReference(referenceLocation, relatedSymbol, searchLocation, state) {
                var addRef = state.referenceAdder(relatedSymbol, searchLocation);
                if (state.options.implementations) {
                    addImplementationReferences(referenceLocation, addRef, state);
                }
                else {
                    addRef(referenceLocation);
                }
            }
            /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses.  */
            function findConstructorReferences(referenceLocation, sourceFile, search, state) {
                if (ts.isNewExpressionTarget(referenceLocation)) {
                    addReference(referenceLocation, search.symbol, search.location, state);
                }
                var pusher = state.referenceAdder(search.symbol, search.location);
                if (ts.isClassLike(referenceLocation.parent)) {
                    ts.Debug.assert(referenceLocation.parent.name === referenceLocation);
                    // This is the class declaration containing the constructor.
                    findOwnConstructorReferences(search.symbol, sourceFile, pusher);
                }
                else {
                    // If this class appears in `extends C`, then the extending class' "super" calls are references.
                    var classExtending = tryGetClassByExtendingIdentifier(referenceLocation);
                    if (classExtending && ts.isClassLike(classExtending)) {
                        findSuperConstructorAccesses(classExtending, pusher);
                    }
                }
            }
            function getPropertyAccessExpressionFromRightHandSide(node) {
                return ts.isRightSideOfPropertyAccess(node) && node.parent;
            }
            /**
             * `classSymbol` is the class where the constructor was defined.
             * Reference the constructor and all calls to `new this()`.
             */
            function findOwnConstructorReferences(classSymbol, sourceFile, addNode) {
                for (var _i = 0, _a = classSymbol.members.get("__constructor" /* Constructor */).declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var ctrKeyword = ts.findChildOfKind(decl, 123 /* ConstructorKeyword */, sourceFile);
                    ts.Debug.assert(decl.kind === 152 /* Constructor */ && !!ctrKeyword);
                    addNode(ctrKeyword);
                }
                classSymbol.exports.forEach(function (member) {
                    var decl = member.valueDeclaration;
                    if (decl && decl.kind === 151 /* MethodDeclaration */) {
                        var body = decl.body;
                        if (body) {
                            forEachDescendantOfKind(body, 99 /* ThisKeyword */, function (thisKeyword) {
                                if (ts.isNewExpressionTarget(thisKeyword)) {
                                    addNode(thisKeyword);
                                }
                            });
                        }
                    }
                });
            }
            /** Find references to `super` in the constructor of an extending class.  */
            function findSuperConstructorAccesses(cls, addNode) {
                var symbol = cls.symbol;
                var ctr = symbol.members.get("__constructor" /* Constructor */);
                if (!ctr) {
                    return;
                }
                for (var _i = 0, _a = ctr.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    ts.Debug.assert(decl.kind === 152 /* Constructor */);
                    var body = decl.body;
                    if (body) {
                        forEachDescendantOfKind(body, 97 /* SuperKeyword */, function (node) {
                            if (ts.isCallExpressionTarget(node)) {
                                addNode(node);
                            }
                        });
                    }
                }
            }
            function addImplementationReferences(refNode, addReference, state) {
                // Check if we found a function/propertyAssignment/method with an implementation or initializer
                if (ts.isDeclarationName(refNode) && isImplementation(refNode.parent)) {
                    addReference(refNode.parent);
                    return;
                }
                if (refNode.kind !== 71 /* Identifier */) {
                    return;
                }
                if (refNode.parent.kind === 262 /* ShorthandPropertyAssignment */) {
                    // Go ahead and dereference the shorthand assignment by going to its definition
                    getReferenceEntriesForShorthandPropertyAssignment(refNode, state.checker, addReference);
                }
                // Check if the node is within an extends or implements clause
                var containingClass = getContainingClassIfInHeritageClause(refNode);
                if (containingClass) {
                    addReference(containingClass);
                    return;
                }
                // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface
                var containingTypeReference = getContainingTypeReference(refNode);
                if (containingTypeReference && state.markSeenContainingTypeReference(containingTypeReference)) {
                    var parent = containingTypeReference.parent;
                    if (ts.isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) {
                        addReference(parent.initializer);
                    }
                    else if (ts.isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) {
                        var body = parent.body;
                        if (body.kind === 207 /* Block */) {
                            ts.forEachReturnStatement(body, function (returnStatement) {
                                if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) {
                                    addReference(returnStatement.expression);
                                }
                            });
                        }
                        else if (isImplementationExpression(body)) {
                            addReference(body);
                        }
                    }
                    else if (ts.isAssertionExpression(parent) && isImplementationExpression(parent.expression)) {
                        addReference(parent.expression);
                    }
                }
            }
            function getSymbolsForClassAndInterfaceComponents(type, result) {
                if (result === void 0) { result = []; }
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var componentType = _a[_i];
                    if (componentType.symbol && componentType.symbol.getFlags() & (32 /* Class */ | 64 /* Interface */)) {
                        result.push(componentType.symbol);
                    }
                    if (componentType.getFlags() & 196608 /* UnionOrIntersection */) {
                        getSymbolsForClassAndInterfaceComponents(componentType, result);
                    }
                }
                return result;
            }
            function getContainingTypeReference(node) {
                var topLevelTypeReference = undefined;
                while (node) {
                    if (ts.isTypeNode(node)) {
                        topLevelTypeReference = node;
                    }
                    node = node.parent;
                }
                return topLevelTypeReference;
            }
            function getContainingClassIfInHeritageClause(node) {
                if (node && node.parent) {
                    if (node.kind === 201 /* ExpressionWithTypeArguments */
                        && node.parent.kind === 259 /* HeritageClause */
                        && ts.isClassLike(node.parent.parent)) {
                        return node.parent.parent;
                    }
                    else if (node.kind === 71 /* Identifier */ || node.kind === 179 /* PropertyAccessExpression */) {
                        return getContainingClassIfInHeritageClause(node.parent);
                    }
                }
                return undefined;
            }
            /**
             * Returns true if this is an expression that can be considered an implementation
             */
            function isImplementationExpression(node) {
                switch (node.kind) {
                    case 185 /* ParenthesizedExpression */:
                        return isImplementationExpression(node.expression);
                    case 187 /* ArrowFunction */:
                    case 186 /* FunctionExpression */:
                    case 178 /* ObjectLiteralExpression */:
                    case 199 /* ClassExpression */:
                    case 177 /* ArrayLiteralExpression */:
                        return true;
                    default:
                        return false;
                }
            }
            /**
             * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol
             * is an interface, determines if some ancestor of the child symbol extends or inherits from it.
             * Also takes in a cache of previous results which makes this slightly more efficient and is
             * necessary to avoid potential loops like so:
             *     class A extends B { }
             *     class B extends A { }
             *
             * We traverse the AST rather than using the type checker because users are typically only interested
             * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling
             * implementations of types that share a common ancestor with the type whose implementation we are
             * searching for need to be filtered out of the results. The type checker doesn't let us make the
             * distinction between structurally compatible implementations and explicit implementations, so we
             * must use the AST.
             *
             * @param child         A class or interface Symbol
             * @param parent        Another class or interface Symbol
             * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results
             */
            function explicitlyInheritsFrom(child, parent, cachedResults, checker) {
                var parentIsInterface = parent.getFlags() & 64 /* Interface */;
                return searchHierarchy(child);
                function searchHierarchy(symbol) {
                    if (symbol === parent) {
                        return true;
                    }
                    var key = ts.getSymbolId(symbol) + "," + ts.getSymbolId(parent);
                    var cached = cachedResults.get(key);
                    if (cached !== undefined) {
                        return cached;
                    }
                    // Set the key so that we don't infinitely recurse
                    cachedResults.set(key, false);
                    var inherits = ts.forEach(symbol.getDeclarations(), function (declaration) {
                        if (ts.isClassLike(declaration)) {
                            if (parentIsInterface) {
                                var interfaceReferences = ts.getClassImplementsHeritageClauseElements(declaration);
                                if (interfaceReferences) {
                                    for (var _i = 0, interfaceReferences_1 = interfaceReferences; _i < interfaceReferences_1.length; _i++) {
                                        var typeReference = interfaceReferences_1[_i];
                                        if (searchTypeReference(typeReference)) {
                                            return true;
                                        }
                                    }
                                }
                            }
                            return searchTypeReference(ts.getClassExtendsHeritageClauseElement(declaration));
                        }
                        else if (declaration.kind === 230 /* InterfaceDeclaration */) {
                            if (parentIsInterface) {
                                return ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), searchTypeReference);
                            }
                        }
                        return false;
                    });
                    cachedResults.set(key, inherits);
                    return inherits;
                }
                function searchTypeReference(typeReference) {
                    if (typeReference) {
                        var type = checker.getTypeAtLocation(typeReference);
                        if (type && type.symbol) {
                            return searchHierarchy(type.symbol);
                        }
                    }
                    return false;
                }
            }
            function getReferencesForSuperKeyword(superKeyword) {
                var searchSpaceNode = ts.getSuperContainer(superKeyword, /*stopOnFunctions*/ false);
                if (!searchSpaceNode) {
                    return undefined;
                }
                // Whether 'super' occurs in a static context within a class.
                var staticFlag = 32 /* Static */;
                switch (searchSpaceNode.kind) {
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                    case 152 /* Constructor */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    default:
                        return undefined;
                }
                var references = [];
                var sourceFile = searchSpaceNode.getSourceFile();
                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode);
                for (var _i = 0, possiblePositions_3 = possiblePositions; _i < possiblePositions_3.length; _i++) {
                    var position = possiblePositions_3[_i];
                    var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
                    if (!node || node.kind !== 97 /* SuperKeyword */) {
                        continue;
                    }
                    var container = ts.getSuperContainer(node, /*stopOnFunctions*/ false);
                    // If we have a 'super' container, we must have an enclosing class.
                    // Now make sure the owning class is the same as the search-space
                    // and has the same static qualifier as the original 'super's owner.
                    if (container && (32 /* Static */ & ts.getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) {
                        references.push(FindAllReferences.nodeEntry(node));
                    }
                }
                return [{ definition: { type: "symbol", symbol: searchSpaceNode.symbol, node: superKeyword }, references: references }];
            }
            function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles, cancellationToken) {
                var searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
                // Whether 'this' occurs in a static context within a class.
                var staticFlag = 32 /* Static */;
                switch (searchSpaceNode.kind) {
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                        if (ts.isObjectLiteralMethod(searchSpaceNode)) {
                            break;
                        }
                    // falls through
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                    case 152 /* Constructor */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    case 265 /* SourceFile */:
                        if (ts.isExternalModule(searchSpaceNode)) {
                            return undefined;
                        }
                    // falls through
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                        break;
                    // Computed properties in classes are not handled here because references to this are illegal,
                    // so there is no point finding references to them.
                    default:
                        return undefined;
                }
                var references = [];
                var possiblePositions;
                if (searchSpaceNode.kind === 265 /* SourceFile */) {
                    ts.forEach(sourceFiles, function (sourceFile) {
                        cancellationToken.throwIfCancellationRequested();
                        possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this");
                        getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references);
                    });
                }
                else {
                    var sourceFile = searchSpaceNode.getSourceFile();
                    possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode);
                    getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references);
                }
                return [{
                        definition: { type: "this", node: thisOrSuperKeyword },
                        references: references
                    }];
                function getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result) {
                    ts.forEach(possiblePositions, function (position) {
                        var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
                        if (!node || !ts.isThis(node)) {
                            return;
                        }
                        var container = ts.getThisContainer(node, /* includeArrowFunctions */ false);
                        switch (searchSpaceNode.kind) {
                            case 186 /* FunctionExpression */:
                            case 228 /* FunctionDeclaration */:
                                if (searchSpaceNode.symbol === container.symbol) {
                                    result.push(FindAllReferences.nodeEntry(node));
                                }
                                break;
                            case 151 /* MethodDeclaration */:
                            case 150 /* MethodSignature */:
                                if (ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) {
                                    result.push(FindAllReferences.nodeEntry(node));
                                }
                                break;
                            case 199 /* ClassExpression */:
                            case 229 /* ClassDeclaration */:
                                // Make sure the container belongs to the same class
                                // and has the appropriate static modifier from the original container.
                                if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (ts.getModifierFlags(container) & 32 /* Static */) === staticFlag) {
                                    result.push(FindAllReferences.nodeEntry(node));
                                }
                                break;
                            case 265 /* SourceFile */:
                                if (container.kind === 265 /* SourceFile */ && !ts.isExternalModule(container)) {
                                    result.push(FindAllReferences.nodeEntry(node));
                                }
                                break;
                        }
                    });
                }
            }
            function getReferencesForStringLiteral(node, sourceFiles, cancellationToken) {
                var references = [];
                for (var _i = 0, sourceFiles_7 = sourceFiles; _i < sourceFiles_7.length; _i++) {
                    var sourceFile = sourceFiles_7[_i];
                    cancellationToken.throwIfCancellationRequested();
                    var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, node.text);
                    getReferencesForStringLiteralInFile(sourceFile, node.text, possiblePositions, references);
                }
                return [{
                        definition: { type: "string", node: node },
                        references: references
                    }];
                function getReferencesForStringLiteralInFile(sourceFile, searchText, possiblePositions, references) {
                    for (var _i = 0, possiblePositions_4 = possiblePositions; _i < possiblePositions_4.length; _i++) {
                        var position = possiblePositions_4[_i];
                        var node_7 = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
                        if (node_7 && node_7.kind === 9 /* StringLiteral */ && node_7.text === searchText) {
                            references.push(FindAllReferences.nodeEntry(node_7, /*isInString*/ true));
                        }
                    }
                }
            }
            // For certain symbol kinds, we need to include other symbols in the search set.
            // This is not needed when searching for re-exports.
            function populateSearchSymbolSet(symbol, location, checker, implementations) {
                // The search set contains at least the current symbol
                var result = [symbol];
                var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(location);
                if (containingObjectLiteralElement) {
                    // If the location is name of property symbol from object literal destructuring pattern
                    // Search the property symbol
                    //      for ( { property: p2 } of elems) { }
                    if (containingObjectLiteralElement.kind !== 262 /* ShorthandPropertyAssignment */) {
                        var propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
                        if (propertySymbol) {
                            result.push(propertySymbol);
                        }
                    }
                    // If the location is in a context sensitive location (i.e. in an object literal) try
                    // to get a contextual type for it, and add the property symbol from the contextual
                    // type to the search set
                    ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), function (contextualSymbol) {
                        ts.addRange(result, checker.getRootSymbols(contextualSymbol));
                    });
                    /* Because in short-hand property assignment, location has two meaning : property name and as value of the property
                     * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
                     * property name and variable declaration of the identifier.
                     * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service
                     * should show both 'name' in 'obj' and 'name' in variable declaration
                     *      const name = "Foo";
                     *      const obj = { name };
                     * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment
                     * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration
                     * will be included correctly.
                     */
                    var shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent);
                    if (shorthandValueSymbol) {
                        result.push(shorthandValueSymbol);
                    }
                }
                // If the symbol.valueDeclaration is a property parameter declaration,
                // we should include both parameter declaration symbol and property declaration symbol
                // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals.
                // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members
                if (symbol.valueDeclaration && symbol.valueDeclaration.kind === 146 /* Parameter */ &&
                    ts.isParameterPropertyDeclaration(symbol.valueDeclaration)) {
                    ts.addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name));
                }
                // If this is symbol of binding element without propertyName declaration in Object binding pattern
                // Include the property in the search
                var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
                if (bindingElementPropertySymbol) {
                    result.push(bindingElementPropertySymbol);
                    addRootSymbols(bindingElementPropertySymbol);
                }
                addRootSymbols(symbol);
                return result;
                function addRootSymbols(sym) {
                    // If this is a union property, add all the symbols from all its source symbols in all unioned types.
                    // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
                    for (var _i = 0, _a = checker.getRootSymbols(sym); _i < _a.length; _i++) {
                        var rootSymbol = _a[_i];
                        if (rootSymbol !== sym) {
                            result.push(rootSymbol);
                        }
                        // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
                        if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
                            getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ ts.createSymbolTable(), checker);
                        }
                    }
                }
            }
            /**
             * Find symbol of the given property-name and add the symbol to the given result array
             * @param symbol a symbol to start searching for the given propertyName
             * @param propertyName a name of property to search for
             * @param result an array of symbol of found property symbols
             * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol.
             *                                The value of previousIterationSymbol is undefined when the function is first called.
             */
            function getPropertySymbolsFromBaseTypes(symbol, propertyName, result, previousIterationSymbolsCache, checker) {
                if (!symbol) {
                    return;
                }
                // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited
                // This is particularly important for the following cases, so that we do not infinitely visit the same symbol.
                // For example:
                //      interface C extends C {
                //          /*findRef*/propName: string;
                //      }
                // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName,
                // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined,
                // the function will add any found symbol of the property-name, then its sub-routine will call
                // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already
                // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol.
                if (previousIterationSymbolsCache.has(symbol.escapedName)) {
                    return;
                }
                if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                    ts.forEach(symbol.getDeclarations(), function (declaration) {
                        if (ts.isClassLike(declaration)) {
                            getPropertySymbolFromTypeReference(ts.getClassExtendsHeritageClauseElement(declaration));
                            ts.forEach(ts.getClassImplementsHeritageClauseElements(declaration), getPropertySymbolFromTypeReference);
                        }
                        else if (declaration.kind === 230 /* InterfaceDeclaration */) {
                            ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), getPropertySymbolFromTypeReference);
                        }
                    });
                }
                return;
                function getPropertySymbolFromTypeReference(typeReference) {
                    if (typeReference) {
                        var type = checker.getTypeAtLocation(typeReference);
                        if (type) {
                            var propertySymbol = checker.getPropertyOfType(type, propertyName);
                            if (propertySymbol) {
                                result.push.apply(result, checker.getRootSymbols(propertySymbol));
                            }
                            // Visit the typeReference as well to see if it directly or indirectly use that property
                            previousIterationSymbolsCache.set(symbol.escapedName, symbol);
                            getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache, checker);
                        }
                    }
                }
            }
            function getRelatedSymbol(search, referenceSymbol, referenceLocation, state) {
                if (search.includes(referenceSymbol)) {
                    return referenceSymbol;
                }
                // If the reference location is in an object literal, try to get the contextual type for the
                // object literal, lookup the property symbol in the contextual type, and use this symbol to
                // compare to our searchSymbol
                var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(referenceLocation);
                if (containingObjectLiteralElement) {
                    var contextualSymbol = ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, state.checker), function (contextualSymbol) {
                        return ts.find(state.checker.getRootSymbols(contextualSymbol), search.includes);
                    });
                    if (contextualSymbol) {
                        return contextualSymbol;
                    }
                    // If the reference location is the name of property from object literal destructuring pattern
                    // Get the property symbol from the object literal's type and look if thats the search symbol
                    // In below eg. get 'property' from type of elems iterating type
                    //      for ( { property: p2 } of elems) { }
                    var propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, state.checker);
                    if (propertySymbol && search.includes(propertySymbol)) {
                        return propertySymbol;
                    }
                }
                // If the reference location is the binding element and doesn't have property name
                // then include the binding element in the related symbols
                //      let { a } : { a };
                var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, state.checker);
                if (bindingElementPropertySymbol) {
                    var fromBindingElement = findRootSymbol(bindingElementPropertySymbol);
                    if (fromBindingElement)
                        return fromBindingElement;
                }
                return findRootSymbol(referenceSymbol);
                function findRootSymbol(sym) {
                    // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
                    // Or a union property, use its underlying unioned symbols
                    return ts.forEach(state.checker.getRootSymbols(sym), function (rootSymbol) {
                        // if it is in the list, then we are done
                        if (search.includes(rootSymbol)) {
                            return rootSymbol;
                        }
                        // Finally, try all properties with the same name in any type the containing type extended or implemented, and
                        // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the
                        // parent symbol
                        if (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
                            // Parents will only be defined if implementations is true
                            if (search.parents && !ts.some(search.parents, function (parent) { return explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker); })) {
                                return undefined;
                            }
                            var result = [];
                            getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ ts.createSymbolTable(), state.checker);
                            return ts.find(result, search.includes);
                        }
                        return undefined;
                    });
                }
            }
            function getNameFromObjectLiteralElement(node) {
                if (node.name.kind === 144 /* ComputedPropertyName */) {
                    var nameExpression = node.name.expression;
                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
                    if (ts.isStringOrNumericLiteral(nameExpression)) {
                        return nameExpression.text;
                    }
                    return undefined;
                }
                return ts.getTextOfIdentifierOrLiteral(node.name);
            }
            /** Gets all symbols for one property. Does not get symbols for every property. */
            function getPropertySymbolsFromContextualType(node, checker) {
                var objectLiteral = node.parent;
                var contextualType = checker.getContextualType(objectLiteral);
                var name = getNameFromObjectLiteralElement(node);
                if (name && contextualType) {
                    var result_6 = [];
                    var symbol = contextualType.getProperty(name);
                    if (symbol) {
                        result_6.push(symbol);
                    }
                    if (contextualType.flags & 65536 /* Union */) {
                        ts.forEach(contextualType.types, function (t) {
                            var symbol = t.getProperty(name);
                            if (symbol) {
                                result_6.push(symbol);
                            }
                        });
                    }
                    return result_6;
                }
                return undefined;
            }
            /**
             * Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations
             * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class
             * then we need to widen the search to include type positions as well.
             * On the contrary, if we are searching for "Bar" in type position and we trace bar to an interface, and an uninstantiated
             * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module)
             * do not intersect in any of the three spaces.
             */
            function getIntersectingMeaningFromDeclarations(meaning, declarations) {
                if (declarations) {
                    var lastIterationMeaning = void 0;
                    do {
                        // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module]
                        // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module
                        // intersects with the class in the value space.
                        // To achieve that we will keep iterating until the result stabilizes.
                        // Remember the last meaning
                        lastIterationMeaning = meaning;
                        for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) {
                            var declaration = declarations_10[_i];
                            var declarationMeaning = ts.getMeaningFromDeclaration(declaration);
                            if (declarationMeaning & meaning) {
                                meaning |= declarationMeaning;
                            }
                        }
                    } while (meaning !== lastIterationMeaning);
                }
                return meaning;
            }
            function isImplementation(node) {
                if (!node) {
                    return false;
                }
                else if (ts.isVariableLike(node)) {
                    if (node.initializer) {
                        return true;
                    }
                    else if (node.kind === 226 /* VariableDeclaration */) {
                        var parentStatement = getParentStatementOfVariableDeclaration(node);
                        return parentStatement && ts.hasModifier(parentStatement, 2 /* Ambient */);
                    }
                }
                else if (ts.isFunctionLike(node)) {
                    return !!node.body || ts.hasModifier(node, 2 /* Ambient */);
                }
                else {
                    switch (node.kind) {
                        case 229 /* ClassDeclaration */:
                        case 199 /* ClassExpression */:
                        case 232 /* EnumDeclaration */:
                        case 233 /* ModuleDeclaration */:
                            return true;
                    }
                }
                return false;
            }
            function getParentStatementOfVariableDeclaration(node) {
                if (node.parent && node.parent.parent && node.parent.parent.kind === 208 /* VariableStatement */) {
                    ts.Debug.assert(node.parent.kind === 227 /* VariableDeclarationList */);
                    return node.parent.parent;
                }
            }
            function getReferenceEntriesForShorthandPropertyAssignment(node, checker, addReference) {
                var refSymbol = checker.getSymbolAtLocation(node);
                var shorthandSymbol = checker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration);
                if (shorthandSymbol) {
                    for (var _i = 0, _a = shorthandSymbol.getDeclarations(); _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (ts.getMeaningFromDeclaration(declaration) & 1 /* Value */) {
                            addReference(declaration);
                        }
                    }
                }
            }
            Core.getReferenceEntriesForShorthandPropertyAssignment = getReferenceEntriesForShorthandPropertyAssignment;
            function forEachDescendantOfKind(node, kind, action) {
                ts.forEachChild(node, function (child) {
                    if (child.kind === kind) {
                        action(child);
                    }
                    forEachDescendantOfKind(child, kind, action);
                });
            }
            /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */
            function tryGetClassByExtendingIdentifier(node) {
                return ts.tryGetClassExtendingExpressionWithTypeArguments(ts.climbPastPropertyAccess(node).parent);
            }
            function isNameOfExternalModuleImportOrDeclaration(node) {
                if (node.kind === 9 /* StringLiteral */) {
                    return ts.isNameOfModuleDeclaration(node) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node);
                }
                return false;
            }
            /**
             * If we are just looking for implementations and this is a property access expression, we need to get the
             * symbol of the local type of the symbol the property is being accessed on. This is because our search
             * symbol may have a different parent symbol if the local type's symbol does not declare the property
             * being accessed (i.e. it is declared in some parent class or interface)
             */
            function getParentSymbolsOfPropertyAccess(location, symbol, checker) {
                var propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(location);
                if (!propertyAccessExpression) {
                    return undefined;
                }
                var localParentType = checker.getTypeAtLocation(propertyAccessExpression.expression);
                if (!localParentType) {
                    return undefined;
                }
                if (localParentType.symbol && localParentType.symbol.flags & (32 /* Class */ | 64 /* Interface */) && localParentType.symbol !== symbol.parent) {
                    return [localParentType.symbol];
                }
                else if (localParentType.flags & 196608 /* UnionOrIntersection */) {
                    return getSymbolsForClassAndInterfaceComponents(localParentType);
                }
            }
        })(Core = FindAllReferences.Core || (FindAllReferences.Core = {}));
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var GoToDefinition;
    (function (GoToDefinition) {
        function getDefinitionAtPosition(program, sourceFile, position) {
            /// Triple slash reference comments
            var comment = findReferenceInPosition(sourceFile.referencedFiles, position);
            if (comment) {
                var referenceFile = ts.tryResolveScriptReference(program, sourceFile, comment);
                if (referenceFile) {
                    return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)];
                }
                // Might still be on jsdoc, so keep looking.
            }
            // Type reference directives
            var typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
            if (typeReferenceDirective) {
                var referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName);
                return referenceFile && referenceFile.resolvedFileName &&
                    [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)];
            }
            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
            if (node === sourceFile) {
                return undefined;
            }
            // Labels
            if (ts.isJumpStatementTarget(node)) {
                var labelName = node.text;
                var label = ts.getTargetLabel(node.parent, labelName);
                return label ? [createDefinitionInfoFromName(label, "label" /* label */, labelName, /*containerName*/ undefined)] : undefined;
            }
            var typeChecker = program.getTypeChecker();
            var calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
            if (calledDeclaration) {
                return [createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration)];
            }
            var symbol = typeChecker.getSymbolAtLocation(node);
            // Could not find a symbol e.g. node is string or number keyword,
            // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
            if (!symbol) {
                return undefined;
            }
            // If this is an alias, and the request came at the declaration location
            // get the aliased symbol instead. This allows for goto def on an import e.g.
            //   import {A, B} from "mod";
            // to jump to the implementation directly.
            if (symbol.flags & 2097152 /* Alias */ && shouldSkipAlias(node, symbol.declarations[0])) {
                var aliased = typeChecker.getAliasedSymbol(symbol);
                if (aliased.declarations) {
                    symbol = aliased;
                }
            }
            // Because name in short-hand property assignment has two different meanings: property name and property value,
            // using go-to-definition at such position should go to the variable declaration of the property value rather than
            // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
            // is performed at the location of property access, we would like to go to definition of the property in the short-hand
            // assignment. This case and others are handled by the following code.
            if (node.parent.kind === 262 /* ShorthandPropertyAssignment */) {
                var shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
                if (!shorthandSymbol) {
                    return [];
                }
                var shorthandDeclarations = shorthandSymbol.getDeclarations();
                var shorthandSymbolKind_1 = ts.SymbolDisplay.getSymbolKind(typeChecker, shorthandSymbol, node);
                var shorthandSymbolName_1 = typeChecker.symbolToString(shorthandSymbol);
                var shorthandContainerName_1 = typeChecker.symbolToString(symbol.parent, node);
                return ts.map(shorthandDeclarations, function (declaration) { return createDefinitionInfo(declaration, shorthandSymbolKind_1, shorthandSymbolName_1, shorthandContainerName_1); });
            }
            // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
            // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
            // and return the property declaration for the referenced property.
            // For example:
            //      import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
            //
            //      function bar<T>(onfulfilled: (value: T) => void) { //....}
            //      interface Test {
            //          pr/*destination*/op1: number
            //      }
            //      bar<Test>(({pr/*goto*/op1})=>{});
            if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
                (node === (node.parent.propertyName || node.parent.name))) {
                var type = typeChecker.getTypeAtLocation(node.parent.parent);
                if (type) {
                    var propSymbols = ts.getPropertySymbolsFromType(type, node);
                    if (propSymbols) {
                        return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); });
                    }
                }
            }
            // If the current location we want to find its definition is in an object literal, try to get the contextual type for the
            // object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
            // For example
            //      interface Props{
            //          /*first*/prop1: number
            //          prop2: boolean
            //      }
            //      function Foo(arg: Props) {}
            //      Foo( { pr/*1*/op1: 10, prop2: true })
            var element = ts.getContainingObjectLiteralElement(node);
            if (element && typeChecker.getContextualType(element.parent)) {
                return ts.flatMap(ts.getPropertySymbolsFromContextualType(typeChecker, element), function (propertySymbol) {
                    return getDefinitionFromSymbol(typeChecker, propertySymbol, node);
                });
            }
            return getDefinitionFromSymbol(typeChecker, symbol, node);
        }
        GoToDefinition.getDefinitionAtPosition = getDefinitionAtPosition;
        /// Goto type
        function getTypeDefinitionAtPosition(typeChecker, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
            if (node === sourceFile) {
                return undefined;
            }
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol) {
                return undefined;
            }
            var type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
            if (!type) {
                return undefined;
            }
            if (type.flags & 65536 /* Union */ && !(type.flags & 16 /* Enum */)) {
                var result_7 = [];
                ts.forEach(type.types, function (t) {
                    if (t.symbol) {
                        ts.addRange(/*to*/ result_7, /*from*/ getDefinitionFromSymbol(typeChecker, t.symbol, node));
                    }
                });
                return result_7;
            }
            if (!type.symbol) {
                return undefined;
            }
            return getDefinitionFromSymbol(typeChecker, type.symbol, node);
        }
        GoToDefinition.getTypeDefinitionAtPosition = getTypeDefinitionAtPosition;
        // Go to the original declaration for cases:
        //
        //   (1) when the aliased symbol was declared in the location(parent).
        //   (2) when the aliased symbol is originating from an import.
        //
        function shouldSkipAlias(node, declaration) {
            if (node.kind !== 71 /* Identifier */) {
                return false;
            }
            if (node.parent === declaration) {
                return true;
            }
            switch (declaration.kind) {
                case 239 /* ImportClause */:
                case 237 /* ImportEqualsDeclaration */:
                    return true;
                case 242 /* ImportSpecifier */:
                    return declaration.parent.kind === 241 /* NamedImports */;
                default:
                    return false;
            }
        }
        function getDefinitionFromSymbol(typeChecker, symbol, node) {
            var result = [];
            var declarations = symbol.getDeclarations();
            var _a = getSymbolInfo(typeChecker, symbol, node), symbolName = _a.symbolName, symbolKind = _a.symbolKind, containerName = _a.containerName;
            if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
                !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
                // Just add all the declarations.
                ts.forEach(declarations, function (declaration) {
                    result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
                });
            }
            return result;
            function tryAddConstructSignature(symbol, location, symbolKind, symbolName, containerName, result) {
                // Applicable only if we are in a new expression, or we are on a constructor declaration
                // and in either case the symbol has a construct signature definition, i.e. class
                if (ts.isNewExpressionTarget(location) || location.kind === 123 /* ConstructorKeyword */) {
                    if (symbol.flags & 32 /* Class */) {
                        // Find the first class-like declaration and try to get the construct signature.
                        for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) {
                            var declaration = _a[_i];
                            if (ts.isClassLike(declaration)) {
                                return tryAddSignature(declaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
                            }
                        }
                        ts.Debug.fail("Expected declaration to have at least one class-like declaration");
                    }
                }
                return false;
            }
            function tryAddCallSignature(symbol, location, symbolKind, symbolName, containerName, result) {
                if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location) || ts.isNameOfFunctionDeclaration(location)) {
                    return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
                }
                return false;
            }
            function tryAddSignature(signatureDeclarations, selectConstructors, symbolKind, symbolName, containerName, result) {
                if (!signatureDeclarations) {
                    return false;
                }
                var declarations = [];
                var definition;
                for (var _i = 0, signatureDeclarations_1 = signatureDeclarations; _i < signatureDeclarations_1.length; _i++) {
                    var d = signatureDeclarations_1[_i];
                    if (selectConstructors ? d.kind === 152 /* Constructor */ : isSignatureDeclaration(d)) {
                        declarations.push(d);
                        if (d.body)
                            definition = d;
                    }
                }
                if (declarations.length) {
                    result.push(createDefinitionInfo(definition || ts.lastOrUndefined(declarations), symbolKind, symbolName, containerName));
                    return true;
                }
                return false;
            }
        }
        function isSignatureDeclaration(node) {
            switch (node.kind) {
                case 152 /* Constructor */:
                case 228 /* FunctionDeclaration */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                    return true;
                default:
                    return false;
            }
        }
        /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */
        function createDefinitionInfo(node, symbolKind, symbolName, containerName) {
            return createDefinitionInfoFromName(ts.getNameOfDeclaration(node) || node, symbolKind, symbolName, containerName);
        }
        /** Creates a DefinitionInfo directly from the name of a declaration. */
        function createDefinitionInfoFromName(name, symbolKind, symbolName, containerName) {
            var sourceFile = name.getSourceFile();
            return {
                fileName: sourceFile.fileName,
                textSpan: ts.createTextSpanFromNode(name, sourceFile),
                kind: symbolKind,
                name: symbolName,
                containerKind: undefined,
                containerName: containerName
            };
        }
        function getSymbolInfo(typeChecker, symbol, node) {
            return {
                symbolName: typeChecker.symbolToString(symbol),
                symbolKind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node),
                containerName: symbol.parent ? typeChecker.symbolToString(symbol.parent, node) : ""
            };
        }
        function createDefinitionFromSignatureDeclaration(typeChecker, decl) {
            var _a = getSymbolInfo(typeChecker, decl.symbol, decl), symbolName = _a.symbolName, symbolKind = _a.symbolKind, containerName = _a.containerName;
            return createDefinitionInfo(decl, symbolKind, symbolName, containerName);
        }
        function findReferenceInPosition(refs, pos) {
            for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) {
                var ref = refs_1[_i];
                if (ref.pos <= pos && pos <= ref.end) {
                    return ref;
                }
            }
            return undefined;
        }
        function getDefinitionInfoForFileReference(name, targetFileName) {
            return {
                fileName: targetFileName,
                textSpan: ts.createTextSpanFromBounds(0, 0),
                kind: "script" /* scriptElement */,
                name: name,
                containerName: undefined,
                containerKind: undefined
            };
        }
        /** Returns a CallLikeExpression where `node` is the target being invoked. */
        function getAncestorCallLikeExpression(node) {
            var target = climbPastManyPropertyAccesses(node);
            var callLike = target.parent;
            return callLike && ts.isCallLikeExpression(callLike) && ts.getInvokedExpression(callLike) === target && callLike;
        }
        function climbPastManyPropertyAccesses(node) {
            return ts.isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
        }
        function tryGetSignatureDeclaration(typeChecker, node) {
            var callLike = getAncestorCallLikeExpression(node);
            var signature = callLike && typeChecker.getResolvedSignature(callLike);
            if (signature) {
                var decl = signature.declaration;
                if (decl && isSignatureDeclaration(decl)) {
                    return decl;
                }
            }
            // Don't go to a function type, go to the value having that type.
            return undefined;
        }
    })(GoToDefinition = ts.GoToDefinition || (ts.GoToDefinition = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var JsDoc;
    (function (JsDoc) {
        var jsDocTagNames = [
            "augments",
            "author",
            "argument",
            "borrows",
            "class",
            "constant",
            "constructor",
            "constructs",
            "default",
            "deprecated",
            "description",
            "event",
            "example",
            "extends",
            "field",
            "fileOverview",
            "function",
            "ignore",
            "inner",
            "lends",
            "link",
            "memberOf",
            "method",
            "name",
            "namespace",
            "param",
            "private",
            "prop",
            "property",
            "public",
            "requires",
            "returns",
            "see",
            "since",
            "static",
            "throws",
            "type",
            "typedef",
            "version"
        ];
        var jsDocTagNameCompletionEntries;
        var jsDocTagCompletionEntries;
        function getJsDocCommentsFromDeclarations(declarations) {
            // Only collect doc comments from duplicate declarations once:
            // In case of a union property there might be same declaration multiple times
            // which only varies in type parameter
            // Eg. const a: Array<string> | Array<number>; a.length
            // The property length will have two declarations of property length coming
            // from Array<T> - Array<string> and Array<number>
            var documentationComment = [];
            forEachUnique(declarations, function (declaration) {
                ts.forEach(ts.getAllJSDocs(declaration), function (doc) {
                    if (doc.comment) {
                        if (documentationComment.length) {
                            documentationComment.push(ts.lineBreakPart());
                        }
                        documentationComment.push(ts.textPart(doc.comment));
                    }
                });
            });
            return documentationComment;
        }
        JsDoc.getJsDocCommentsFromDeclarations = getJsDocCommentsFromDeclarations;
        function getJsDocTagsFromDeclarations(declarations) {
            // Only collect doc comments from duplicate declarations once.
            var tags = [];
            forEachUnique(declarations, function (declaration) {
                for (var _i = 0, _a = ts.getJSDocTags(declaration); _i < _a.length; _i++) {
                    var tag = _a[_i];
                    if (tag.kind === 276 /* JSDocTag */) {
                        tags.push({ name: tag.tagName.text, text: tag.comment });
                    }
                }
            });
            return tags;
        }
        JsDoc.getJsDocTagsFromDeclarations = getJsDocTagsFromDeclarations;
        /**
         * Iterates through 'array' by index and performs the callback on each element of array until the callback
         * returns a truthy value, then returns that value.
         * If no such value is found, the callback is applied to each element of array and undefined is returned.
         */
        function forEachUnique(array, callback) {
            if (array) {
                for (var i = 0; i < array.length; i++) {
                    if (ts.indexOf(array, array[i]) === i) {
                        var result = callback(array[i], i);
                        if (result) {
                            return result;
                        }
                    }
                }
            }
            return undefined;
        }
        function getJSDocTagNameCompletions() {
            return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                return {
                    name: tagName,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "",
                    sortText: "0",
                };
            }));
        }
        JsDoc.getJSDocTagNameCompletions = getJSDocTagNameCompletions;
        function getJSDocTagCompletions() {
            return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                return {
                    name: "@" + tagName,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "",
                    sortText: "0"
                };
            }));
        }
        JsDoc.getJSDocTagCompletions = getJSDocTagCompletions;
        function getJSDocParameterNameCompletions(tag) {
            if (!ts.isIdentifier(tag.name)) {
                return ts.emptyArray;
            }
            var nameThusFar = tag.name.text;
            var jsdoc = tag.parent;
            var fn = jsdoc.parent;
            if (!ts.isFunctionLike(fn))
                return [];
            return ts.mapDefined(fn.parameters, function (param) {
                if (!ts.isIdentifier(param.name))
                    return undefined;
                var name = param.name.text;
                if (jsdoc.tags.some(function (t) { return t !== tag && ts.isJSDocParameterTag(t) && ts.isIdentifier(t.name) && t.name.escapedText === name; })
                    || nameThusFar !== undefined && !ts.startsWith(name, nameThusFar)) {
                    return undefined;
                }
                return { name: name, kind: "parameter" /* parameterElement */, kindModifiers: "", sortText: "0" };
            });
        }
        JsDoc.getJSDocParameterNameCompletions = getJSDocParameterNameCompletions;
        /**
         * Checks if position points to a valid position to add JSDoc comments, and if so,
         * returns the appropriate template. Otherwise returns an empty string.
         * Valid positions are
         *      - outside of comments, statements, and expressions, and
         *      - preceding a:
         *          - function/constructor/method declaration
         *          - class declarations
         *          - variable statements
         *          - namespace declarations
         *
         * Hosts should ideally check that:
         * - The line is all whitespace up to 'position' before performing the insertion.
         * - If the keystroke sequence "/\*\*" induced the call, we also check that the next
         * non-whitespace character is '*', which (approximately) indicates whether we added
         * the second '*' to complete an existing (JSDoc) comment.
         * @param fileName The file in which to perform the check.
         * @param position The (character-indexed) position in the file where the check should
         * be performed.
         */
        function getDocCommentTemplateAtPosition(newLine, sourceFile, position) {
            // Check if in a context where we don't want to perform any insertion
            if (ts.isInString(sourceFile, position) || ts.isInComment(sourceFile, position) || ts.hasDocComment(sourceFile, position)) {
                return undefined;
            }
            var tokenAtPos = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
            var tokenStart = tokenAtPos.getStart();
            if (!tokenAtPos || tokenStart < position) {
                return undefined;
            }
            var commentOwnerInfo = getCommentOwnerInfo(tokenAtPos);
            if (!commentOwnerInfo) {
                return undefined;
            }
            var commentOwner = commentOwnerInfo.commentOwner, parameters = commentOwnerInfo.parameters;
            if (commentOwner.getStart() < position) {
                return undefined;
            }
            var posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
            var lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
            // replace non-whitespace characters in prefix with spaces.
            var indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, function () { return " "; });
            var isJavaScriptFile = ts.hasJavaScriptFileExtension(sourceFile.fileName);
            var docParams = "";
            if (parameters) {
                for (var i = 0; i < parameters.length; i++) {
                    var currentName = parameters[i].name;
                    var paramName = currentName.kind === 71 /* Identifier */ ?
                        currentName.escapedText :
                        "param" + i;
                    if (isJavaScriptFile) {
                        docParams += indentationStr + " * @param {any} " + paramName + newLine;
                    }
                    else {
                        docParams += indentationStr + " * @param " + paramName + newLine;
                    }
                }
            }
            // A doc comment consists of the following
            // * The opening comment line
            // * the first line (without a param) for the object's untagged info (this is also where the caret ends up)
            // * the '@param'-tagged lines
            // * TODO: other tags.
            // * the closing comment line
            // * if the caret was directly in front of the object, then we add an extra line and indentation.
            var preamble = "/**" + newLine +
                indentationStr + " * ";
            var result = preamble + newLine +
                docParams +
                indentationStr + " */" +
                (tokenStart === position ? newLine + indentationStr : "");
            return { newText: result, caretOffset: preamble.length };
        }
        JsDoc.getDocCommentTemplateAtPosition = getDocCommentTemplateAtPosition;
        function getCommentOwnerInfo(tokenAtPos) {
            // TODO: add support for:
            // - enums/enum members
            // - interfaces
            // - property declarations
            // - potentially property assignments
            for (var commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
                switch (commentOwner.kind) {
                    case 228 /* FunctionDeclaration */:
                    case 151 /* MethodDeclaration */:
                    case 152 /* Constructor */:
                        var parameters = commentOwner.parameters;
                        return { commentOwner: commentOwner, parameters: parameters };
                    case 229 /* ClassDeclaration */:
                        return { commentOwner: commentOwner };
                    case 208 /* VariableStatement */: {
                        var varStatement = commentOwner;
                        var varDeclarations = varStatement.declarationList.declarations;
                        var parameters_1 = varDeclarations.length === 1 && varDeclarations[0].initializer
                            ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
                            : undefined;
                        return { commentOwner: commentOwner, parameters: parameters_1 };
                    }
                    case 265 /* SourceFile */:
                        return undefined;
                    case 233 /* ModuleDeclaration */:
                        // If in walking up the tree, we hit a a nested namespace declaration,
                        // then we must be somewhere within a dotted namespace name; however we don't
                        // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
                        return commentOwner.parent.kind === 233 /* ModuleDeclaration */ ? undefined : { commentOwner: commentOwner };
                    case 194 /* BinaryExpression */: {
                        var be = commentOwner;
                        if (ts.getSpecialPropertyAssignmentKind(be) === 0 /* None */) {
                            return undefined;
                        }
                        var parameters_2 = ts.isFunctionLike(be.right) ? be.right.parameters : ts.emptyArray;
                        return { commentOwner: commentOwner, parameters: parameters_2 };
                    }
                }
            }
        }
        /**
         * Digs into an an initializer or RHS operand of an assignment operation
         * to get the parameters of an apt signature corresponding to a
         * function expression or a class expression.
         *
         * @param rightHandSide the expression which may contain an appropriate set of parameters
         * @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
         */
        function getParametersFromRightHandSideOfAssignment(rightHandSide) {
            while (rightHandSide.kind === 185 /* ParenthesizedExpression */) {
                rightHandSide = rightHandSide.expression;
            }
            switch (rightHandSide.kind) {
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                    return rightHandSide.parameters;
                case 199 /* ClassExpression */:
                    for (var _i = 0, _a = rightHandSide.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        if (member.kind === 152 /* Constructor */) {
                            return member.parameters;
                        }
                    }
                    break;
            }
            return ts.emptyArray;
        }
    })(JsDoc = ts.JsDoc || (ts.JsDoc = {}));
})(ts || (ts = {}));
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
// See LICENSE.txt in the project root for complete license information.
/// <reference path='../compiler/types.ts' />
/// <reference path='../compiler/core.ts' />
/// <reference path='../compiler/commandLineParser.ts' />
/* @internal */
var ts;
(function (ts) {
    var JsTyping;
    (function (JsTyping) {
        /* @internal */
        JsTyping.nodeCoreModuleList = [
            "buffer", "querystring", "events", "http", "cluster",
            "zlib", "os", "https", "punycode", "repl", "readline",
            "vm", "child_process", "url", "dns", "net",
            "dgram", "fs", "path", "string_decoder", "tls",
            "crypto", "stream", "util", "assert", "tty", "domain",
            "constants", "process", "v8", "timers", "console"
        ];
        var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList);
        function loadSafeList(host, safeListPath) {
            var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); });
            return ts.createMapFromTemplate(result.config);
        }
        JsTyping.loadSafeList = loadSafeList;
        function loadTypesMap(host, typesMapPath) {
            var result = ts.readConfigFile(typesMapPath, function (path) { return host.readFile(path); });
            if (result.config) {
                return ts.createMapFromTemplate(result.config.simpleMap);
            }
            return undefined;
        }
        JsTyping.loadTypesMap = loadTypesMap;
        /**
         * @param host is the object providing I/O related operations.
         * @param fileNames are the file names that belong to the same project
         * @param projectRootPath is the path to the project root directory
         * @param safeListPath is the path used to retrieve the safe list
         * @param packageNameToTypingLocation is the map of package names to their cached typing locations
         * @param typeAcquisition is used to customize the typing acquisition process
         * @param compilerOptions are used as a source for typing inference
         */
        function discoverTypings(host, log, fileNames, projectRootPath, safeList, packageNameToTypingLocation, typeAcquisition, unresolvedImports) {
            if (!typeAcquisition || !typeAcquisition.enable) {
                return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
            }
            // A typing name to typing file path mapping
            var inferredTypings = ts.createMap();
            // Only infer typings for .js and .jsx files
            fileNames = ts.mapDefined(fileNames, function (fileName) {
                var path = ts.normalizePath(fileName);
                if (ts.hasJavaScriptFileExtension(path)) {
                    return path;
                }
            });
            var filesToWatch = [];
            if (typeAcquisition.include)
                addInferredTypings(typeAcquisition.include, "Explicitly included types");
            var exclude = typeAcquisition.exclude || [];
            // Directories to search for package.json, bower.json and other typing information
            var possibleSearchDirs = ts.arrayToSet(fileNames, ts.getDirectoryPath);
            possibleSearchDirs.set(projectRootPath, true);
            possibleSearchDirs.forEach(function (_true, searchDir) {
                var packageJsonPath = ts.combinePaths(searchDir, "package.json");
                getTypingNamesFromJson(packageJsonPath, filesToWatch);
                var bowerJsonPath = ts.combinePaths(searchDir, "bower.json");
                getTypingNamesFromJson(bowerJsonPath, filesToWatch);
                var bowerComponentsPath = ts.combinePaths(searchDir, "bower_components");
                getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);
                var nodeModulesPath = ts.combinePaths(searchDir, "node_modules");
                getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
            });
            getTypingNamesFromSourceFileNames(fileNames);
            // add typings for unresolved imports
            if (unresolvedImports) {
                var module = ts.deduplicate(unresolvedImports.map(function (moduleId) { return nodeCoreModules.has(moduleId) ? "node" : moduleId; }));
                addInferredTypings(module, "Inferred typings from unresolved imports");
            }
            // Add the cached typing locations for inferred typings that are already installed
            packageNameToTypingLocation.forEach(function (typingLocation, name) {
                if (inferredTypings.has(name) && inferredTypings.get(name) === undefined) {
                    inferredTypings.set(name, typingLocation);
                }
            });
            // Remove typings that the user has added to the exclude list
            for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) {
                var excludeTypingName = exclude_1[_i];
                var didDelete = inferredTypings.delete(excludeTypingName);
                if (didDelete && log)
                    log("Typing for " + excludeTypingName + " is in exclude list, will be ignored.");
            }
            var newTypingNames = [];
            var cachedTypingPaths = [];
            inferredTypings.forEach(function (inferred, typing) {
                if (inferred !== undefined) {
                    cachedTypingPaths.push(inferred);
                }
                else {
                    newTypingNames.push(typing);
                }
            });
            var result = { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch };
            if (log)
                log("Result: " + JSON.stringify(result));
            return result;
            function addInferredTyping(typingName) {
                if (!inferredTypings.has(typingName)) {
                    inferredTypings.set(typingName, undefined);
                }
            }
            function addInferredTypings(typingNames, message) {
                if (log)
                    log(message + ": " + JSON.stringify(typingNames));
                ts.forEach(typingNames, addInferredTyping);
            }
            /**
             * Get the typing info from common package manager json files like package.json or bower.json
             */
            function getTypingNamesFromJson(jsonPath, filesToWatch) {
                if (!host.fileExists(jsonPath)) {
                    return;
                }
                filesToWatch.push(jsonPath);
                var jsonConfig = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); }).config;
                var jsonTypingNames = ts.flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], ts.getOwnKeys);
                addInferredTypings(jsonTypingNames, "Typing names in '" + jsonPath + "' dependencies");
            }
            /**
             * Infer typing names from given file names. For example, the file name "jquery-min.2.3.4.js"
             * should be inferred to the 'jquery' typing name; and "angular-route.1.2.3.js" should be inferred
             * to the 'angular-route' typing name.
             * @param fileNames are the names for source files in the project
             */
            function getTypingNamesFromSourceFileNames(fileNames) {
                var fromFileNames = ts.mapDefined(fileNames, function (j) {
                    if (!ts.hasJavaScriptFileExtension(j))
                        return undefined;
                    var inferredTypingName = ts.removeFileExtension(ts.getBaseFileName(j.toLowerCase()));
                    var cleanedTypingName = inferredTypingName.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, "");
                    return safeList.get(cleanedTypingName);
                });
                if (fromFileNames.length) {
                    addInferredTypings(fromFileNames, "Inferred typings from file names");
                }
                var hasJsxFile = ts.some(fileNames, function (f) { return ts.fileExtensionIs(f, ".jsx" /* Jsx */); });
                if (hasJsxFile) {
                    if (log)
                        log("Inferred 'react' typings due to presence of '.jsx' extension");
                    addInferredTyping("react");
                }
            }
            /**
             * Infer typing names from packages folder (ex: node_module, bower_components)
             * @param packagesFolderPath is the path to the packages folder
             */
            function getTypingNamesFromPackagesFolder(packagesFolderPath, filesToWatch) {
                filesToWatch.push(packagesFolderPath);
                // Todo: add support for ModuleResolutionHost too
                if (!host.directoryExists(packagesFolderPath)) {
                    return;
                }
                // depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar`
                var fileNames = host.readDirectory(packagesFolderPath, [".json" /* Json */], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
                if (log)
                    log("Searching for typing names in " + packagesFolderPath + "; all files: " + JSON.stringify(fileNames));
                var packageNames = [];
                for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
                    var fileName = fileNames_1[_i];
                    var normalizedFileName = ts.normalizePath(fileName);
                    var baseFileName = ts.getBaseFileName(normalizedFileName);
                    if (baseFileName !== "package.json" && baseFileName !== "bower.json") {
                        continue;
                    }
                    var result_8 = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); });
                    var packageJson = result_8.config;
                    // npm 3's package.json contains a "_requiredBy" field
                    // we should include all the top level module names for npm 2, and only module names whose
                    // "_requiredBy" field starts with "#" or equals "/" for npm 3.
                    if (baseFileName === "package.json" && packageJson._requiredBy &&
                        ts.filter(packageJson._requiredBy, function (r) { return r[0] === "#" || r === "/"; }).length === 0) {
                        continue;
                    }
                    // If the package has its own d.ts typings, those will take precedence. Otherwise the package name will be used
                    // to download d.ts files from DefinitelyTyped
                    if (!packageJson.name) {
                        continue;
                    }
                    var ownTypes = packageJson.types || packageJson.typings;
                    if (ownTypes) {
                        var absolutePath = ts.getNormalizedAbsolutePath(ownTypes, ts.getDirectoryPath(normalizedFileName));
                        if (log)
                            log("    Package '" + packageJson.name + "' provides its own types.");
                        inferredTypings.set(packageJson.name, absolutePath);
                    }
                    else {
                        packageNames.push(packageJson.name);
                    }
                }
                addInferredTypings(packageNames, "    Found package names");
            }
        }
        JsTyping.discoverTypings = discoverTypings;
        var PackageNameValidationResult;
        (function (PackageNameValidationResult) {
            PackageNameValidationResult[PackageNameValidationResult["Ok"] = 0] = "Ok";
            PackageNameValidationResult[PackageNameValidationResult["ScopedPackagesNotSupported"] = 1] = "ScopedPackagesNotSupported";
            PackageNameValidationResult[PackageNameValidationResult["EmptyName"] = 2] = "EmptyName";
            PackageNameValidationResult[PackageNameValidationResult["NameTooLong"] = 3] = "NameTooLong";
            PackageNameValidationResult[PackageNameValidationResult["NameStartsWithDot"] = 4] = "NameStartsWithDot";
            PackageNameValidationResult[PackageNameValidationResult["NameStartsWithUnderscore"] = 5] = "NameStartsWithUnderscore";
            PackageNameValidationResult[PackageNameValidationResult["NameContainsNonURISafeCharacters"] = 6] = "NameContainsNonURISafeCharacters";
        })(PackageNameValidationResult = JsTyping.PackageNameValidationResult || (JsTyping.PackageNameValidationResult = {}));
        var MaxPackageNameLength = 214;
        /**
         * Validates package name using rules defined at https://docs.npmjs.com/files/package.json
         */
        function validatePackageName(packageName) {
            if (!packageName) {
                return 2 /* EmptyName */;
            }
            if (packageName.length > MaxPackageNameLength) {
                return 3 /* NameTooLong */;
            }
            if (packageName.charCodeAt(0) === 46 /* dot */) {
                return 4 /* NameStartsWithDot */;
            }
            if (packageName.charCodeAt(0) === 95 /* _ */) {
                return 5 /* NameStartsWithUnderscore */;
            }
            // check if name is scope package like: starts with @ and has one '/' in the middle
            // scoped packages are not currently supported
            // TODO: when support will be added we'll need to split and check both scope and package name
            if (/^@[^/]+\/[^/]+$/.test(packageName)) {
                return 1 /* ScopedPackagesNotSupported */;
            }
            if (encodeURIComponent(packageName) !== packageName) {
                return 6 /* NameContainsNonURISafeCharacters */;
            }
            return 0 /* Ok */;
        }
        JsTyping.validatePackageName = validatePackageName;
        function renderPackageNameValidationFailure(result, typing) {
            switch (result) {
                case 2 /* EmptyName */:
                    return "Package name '" + typing + "' cannot be empty";
                case 3 /* NameTooLong */:
                    return "Package name '" + typing + "' should be less than " + MaxPackageNameLength + " characters";
                case 4 /* NameStartsWithDot */:
                    return "Package name '" + typing + "' cannot start with '.'";
                case 5 /* NameStartsWithUnderscore */:
                    return "Package name '" + typing + "' cannot start with '_'";
                case 1 /* ScopedPackagesNotSupported */:
                    return "Package '" + typing + "' is scoped and currently is not supported";
                case 6 /* NameContainsNonURISafeCharacters */:
                    return "Package name '" + typing + "' contains non URI safe characters";
                case 0 /* Ok */:
                    throw ts.Debug.fail(); // Shouldn't have called this.
                default:
                    ts.Debug.assertNever(result);
            }
        }
        JsTyping.renderPackageNameValidationFailure = renderPackageNameValidationFailure;
    })(JsTyping = ts.JsTyping || (ts.JsTyping = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var NavigateTo;
    (function (NavigateTo) {
        function getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount, excludeDtsFiles) {
            var patternMatcher = ts.createPatternMatcher(searchValue);
            var rawItems = [];
            var _loop_6 = function (sourceFile) {
                cancellationToken.throwIfCancellationRequested();
                if (excludeDtsFiles && ts.fileExtensionIs(sourceFile.fileName, ".d.ts" /* Dts */)) {
                    return "continue";
                }
                ts.forEachEntry(sourceFile.getNamedDeclarations(), function (declarations, name) {
                    getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, sourceFile.fileName, rawItems);
                });
            };
            // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
            for (var _i = 0, sourceFiles_8 = sourceFiles; _i < sourceFiles_8.length; _i++) {
                var sourceFile = sourceFiles_8[_i];
                _loop_6(sourceFile);
            }
            rawItems.sort(compareNavigateToItems);
            if (maxResultCount !== undefined) {
                rawItems = rawItems.slice(0, maxResultCount);
            }
            return rawItems.map(createNavigateToItem);
        }
        NavigateTo.getNavigateToItems = getNavigateToItems;
        function getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, fileName, rawItems) {
            // First do a quick check to see if the name of the declaration matches the
            // last portion of the (possibly) dotted name they're searching for.
            var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name);
            if (!matches) {
                return; // continue to next named declarations
            }
            for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) {
                var declaration = declarations_11[_i];
                if (!shouldKeepItem(declaration, checker)) {
                    continue;
                }
                // It was a match!  If the pattern has dots in it, then also see if the
                // declaration container matches as well.
                var containerMatches = matches;
                if (patternMatcher.patternContainsDots) {
                    containerMatches = patternMatcher.getMatches(getContainers(declaration), name);
                    if (!containerMatches) {
                        continue;
                    }
                }
                var matchKind = bestMatchKind(containerMatches);
                var isCaseSensitive = allMatchesAreCaseSensitive(containerMatches);
                rawItems.push({ name: name, fileName: fileName, matchKind: matchKind, isCaseSensitive: isCaseSensitive, declaration: declaration });
            }
        }
        function shouldKeepItem(declaration, checker) {
            switch (declaration.kind) {
                case 239 /* ImportClause */:
                case 242 /* ImportSpecifier */:
                case 237 /* ImportEqualsDeclaration */:
                    var importer = checker.getSymbolAtLocation(declaration.name);
                    var imported = checker.getAliasedSymbol(importer);
                    return importer.escapedName !== imported.escapedName;
                default:
                    return true;
            }
        }
        function allMatchesAreCaseSensitive(matches) {
            ts.Debug.assert(matches.length > 0);
            // This is a case sensitive match, only if all the submatches were case sensitive.
            for (var _i = 0, matches_2 = matches; _i < matches_2.length; _i++) {
                var match = matches_2[_i];
                if (!match.isCaseSensitive) {
                    return false;
                }
            }
            return true;
        }
        function tryAddSingleDeclarationName(declaration, containers) {
            if (declaration) {
                var name = ts.getNameOfDeclaration(declaration);
                if (name) {
                    var text = ts.getTextOfIdentifierOrLiteral(name);
                    if (text !== undefined) {
                        containers.unshift(text);
                    }
                    else if (name.kind === 144 /* ComputedPropertyName */) {
                        return tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ true);
                    }
                    else {
                        // Don't know how to add this.
                        return false;
                    }
                }
            }
            return true;
        }
        // Only added the names of computed properties if they're simple dotted expressions, like:
        //
        //      [X.Y.Z]() { }
        function tryAddComputedPropertyName(expression, containers, includeLastPortion) {
            var text = ts.getTextOfIdentifierOrLiteral(expression);
            if (text !== undefined) {
                if (includeLastPortion) {
                    containers.unshift(text);
                }
                return true;
            }
            if (expression.kind === 179 /* PropertyAccessExpression */) {
                var propertyAccess = expression;
                if (includeLastPortion) {
                    containers.unshift(propertyAccess.name.text);
                }
                return tryAddComputedPropertyName(propertyAccess.expression, containers, /*includeLastPortion*/ true);
            }
            return false;
        }
        function getContainers(declaration) {
            var containers = [];
            // First, if we started with a computed property name, then add all but the last
            // portion into the container array.
            var name = ts.getNameOfDeclaration(declaration);
            if (name.kind === 144 /* ComputedPropertyName */) {
                if (!tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) {
                    return undefined;
                }
            }
            // Now, walk up our containers, adding all their names to the container array.
            declaration = ts.getContainerNode(declaration);
            while (declaration) {
                if (!tryAddSingleDeclarationName(declaration, containers)) {
                    return undefined;
                }
                declaration = ts.getContainerNode(declaration);
            }
            return containers;
        }
        function bestMatchKind(matches) {
            ts.Debug.assert(matches.length > 0);
            var bestMatchKind = ts.PatternMatchKind.camelCase;
            for (var _i = 0, matches_3 = matches; _i < matches_3.length; _i++) {
                var match = matches_3[_i];
                var kind = match.kind;
                if (kind < bestMatchKind) {
                    bestMatchKind = kind;
                }
            }
            return bestMatchKind;
        }
        function compareNavigateToItems(i1, i2) {
            // TODO(cyrusn): get the gamut of comparisons that VS already uses here.
            // Right now we just sort by kind first, and then by name of the item.
            // We first sort case insensitively.  So "Aaa" will come before "bar".
            // Then we sort case sensitively, so "aaa" will come before "Aaa".
            return i1.matchKind - i2.matchKind ||
                ts.compareStringsCaseInsensitive(i1.name, i2.name) ||
                ts.compareStrings(i1.name, i2.name);
        }
        function createNavigateToItem(rawItem) {
            var declaration = rawItem.declaration;
            var container = ts.getContainerNode(declaration);
            var containerName = container && ts.getNameOfDeclaration(container);
            return {
                name: rawItem.name,
                kind: ts.getNodeKind(declaration),
                kindModifiers: ts.getNodeModifiers(declaration),
                matchKind: ts.PatternMatchKind[rawItem.matchKind],
                isCaseSensitive: rawItem.isCaseSensitive,
                fileName: rawItem.fileName,
                textSpan: ts.createTextSpanFromNode(declaration),
                // TODO(jfreeman): What should be the containerName when the container has a computed name?
                containerName: containerName ? containerName.text : "",
                containerKind: containerName ? ts.getNodeKind(container) : "" /* unknown */
            };
        }
    })(NavigateTo = ts.NavigateTo || (ts.NavigateTo = {}));
})(ts || (ts = {}));
/// <reference path='services.ts' />
/* @internal */
var ts;
(function (ts) {
    var NavigationBar;
    (function (NavigationBar) {
        /**
         * Matches all whitespace characters in a string. Eg:
         *
         * "app.
         *
         * onactivated"
         *
         * matches because of the newline, whereas
         *
         * "app.onactivated"
         *
         * does not match.
         */
        var whiteSpaceRegex = /\s+/g;
        // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
        var curCancellationToken;
        var curSourceFile;
        /**
         * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
         * `parent` is the current parent and is *not* stored in parentsStack.
         * `startNode` sets a new parent and `endNode` returns to the previous parent.
         */
        var parentsStack = [];
        var parent;
        // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
        var emptyChildItemArray = [];
        function getNavigationBarItems(sourceFile, cancellationToken) {
            curCancellationToken = cancellationToken;
            curSourceFile = sourceFile;
            try {
                return ts.map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
            }
            finally {
                reset();
            }
        }
        NavigationBar.getNavigationBarItems = getNavigationBarItems;
        function getNavigationTree(sourceFile, cancellationToken) {
            curCancellationToken = cancellationToken;
            curSourceFile = sourceFile;
            try {
                return convertToTree(rootNavigationBarNode(sourceFile));
            }
            finally {
                reset();
            }
        }
        NavigationBar.getNavigationTree = getNavigationTree;
        function reset() {
            curSourceFile = undefined;
            curCancellationToken = undefined;
            parentsStack = [];
            parent = undefined;
            emptyChildItemArray = [];
        }
        function nodeText(node) {
            return node.getText(curSourceFile);
        }
        function navigationBarNodeKind(n) {
            return n.node.kind;
        }
        function pushChild(parent, child) {
            if (parent.children) {
                parent.children.push(child);
            }
            else {
                parent.children = [child];
            }
        }
        function rootNavigationBarNode(sourceFile) {
            ts.Debug.assert(!parentsStack.length);
            var root = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 };
            parent = root;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                addChildrenRecursively(statement);
            }
            endNode();
            ts.Debug.assert(!parent && !parentsStack.length);
            return root;
        }
        function addLeafNode(node) {
            pushChild(parent, emptyNavigationBarNode(node));
        }
        function emptyNavigationBarNode(node) {
            return {
                node: node,
                additionalNodes: undefined,
                parent: parent,
                children: undefined,
                indent: parent.indent + 1
            };
        }
        /**
         * Add a new level of NavigationBarNodes.
         * This pushes to the stack, so you must call `endNode` when you are done adding to this node.
         */
        function startNode(node) {
            var navNode = emptyNavigationBarNode(node);
            pushChild(parent, navNode);
            // Save the old parent
            parentsStack.push(parent);
            parent = navNode;
        }
        /** Call after calling `startNode` and adding children to it. */
        function endNode() {
            if (parent.children) {
                mergeChildren(parent.children);
                sortChildren(parent.children);
            }
            parent = parentsStack.pop();
        }
        function addNodeWithRecursiveChild(node, child) {
            startNode(node);
            addChildrenRecursively(child);
            endNode();
        }
        /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */
        function addChildrenRecursively(node) {
            curCancellationToken.throwIfCancellationRequested();
            if (!node || ts.isToken(node)) {
                return;
            }
            switch (node.kind) {
                case 152 /* Constructor */:
                    // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it.
                    var ctr = node;
                    addNodeWithRecursiveChild(ctr, ctr.body);
                    // Parameter properties are children of the class, not the constructor.
                    for (var _i = 0, _a = ctr.parameters; _i < _a.length; _i++) {
                        var param = _a[_i];
                        if (ts.isParameterPropertyDeclaration(param)) {
                            addLeafNode(param);
                        }
                    }
                    break;
                case 151 /* MethodDeclaration */:
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 150 /* MethodSignature */:
                    if (!ts.hasDynamicName(node)) {
                        addNodeWithRecursiveChild(node, node.body);
                    }
                    break;
                case 149 /* PropertyDeclaration */:
                case 148 /* PropertySignature */:
                    if (!ts.hasDynamicName(node)) {
                        addLeafNode(node);
                    }
                    break;
                case 239 /* ImportClause */:
                    var importClause = node;
                    // Handle default import case e.g.:
                    //    import d from "mod";
                    if (importClause.name) {
                        addLeafNode(importClause);
                    }
                    // Handle named bindings in imports e.g.:
                    //    import * as NS from "mod";
                    //    import {a, b as B} from "mod";
                    var namedBindings = importClause.namedBindings;
                    if (namedBindings) {
                        if (namedBindings.kind === 240 /* NamespaceImport */) {
                            addLeafNode(namedBindings);
                        }
                        else {
                            for (var _b = 0, _c = namedBindings.elements; _b < _c.length; _b++) {
                                var element = _c[_b];
                                addLeafNode(element);
                            }
                        }
                    }
                    break;
                case 176 /* BindingElement */:
                case 226 /* VariableDeclaration */:
                    var _d = node, name = _d.name, initializer = _d.initializer;
                    if (ts.isBindingPattern(name)) {
                        addChildrenRecursively(name);
                    }
                    else if (initializer && isFunctionOrClassExpression(initializer)) {
                        if (initializer.name) {
                            // Don't add a node for the VariableDeclaration, just for the initializer.
                            addChildrenRecursively(initializer);
                        }
                        else {
                            // Add a node for the VariableDeclaration, but not for the initializer.
                            startNode(node);
                            ts.forEachChild(initializer, addChildrenRecursively);
                            endNode();
                        }
                    }
                    else {
                        addNodeWithRecursiveChild(node, initializer);
                    }
                    break;
                case 187 /* ArrowFunction */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                    addNodeWithRecursiveChild(node, node.body);
                    break;
                case 232 /* EnumDeclaration */:
                    startNode(node);
                    for (var _e = 0, _f = node.members; _e < _f.length; _e++) {
                        var member = _f[_e];
                        if (!isComputedProperty(member)) {
                            addLeafNode(member);
                        }
                    }
                    endNode();
                    break;
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                case 230 /* InterfaceDeclaration */:
                    startNode(node);
                    for (var _g = 0, _h = node.members; _g < _h.length; _g++) {
                        var member = _h[_g];
                        addChildrenRecursively(member);
                    }
                    endNode();
                    break;
                case 233 /* ModuleDeclaration */:
                    addNodeWithRecursiveChild(node, getInteriorModule(node).body);
                    break;
                case 246 /* ExportSpecifier */:
                case 237 /* ImportEqualsDeclaration */:
                case 157 /* IndexSignature */:
                case 155 /* CallSignature */:
                case 156 /* ConstructSignature */:
                case 231 /* TypeAliasDeclaration */:
                    addLeafNode(node);
                    break;
                default:
                    if (ts.hasJSDocNodes(node)) {
                        ts.forEach(node.jsDoc, function (jsDoc) {
                            ts.forEach(jsDoc.tags, function (tag) {
                                if (tag.kind === 283 /* JSDocTypedefTag */) {
                                    addLeafNode(tag);
                                }
                            });
                        });
                    }
                    ts.forEachChild(node, addChildrenRecursively);
            }
        }
        /** Merge declarations of the same kind. */
        function mergeChildren(children) {
            var nameToItems = ts.createMap();
            ts.filterMutate(children, function (child) {
                var declName = ts.getNameOfDeclaration(child.node);
                var name = declName && nodeText(declName);
                if (!name) {
                    // Anonymous items are never merged.
                    return true;
                }
                var itemsWithSameName = nameToItems.get(name);
                if (!itemsWithSameName) {
                    nameToItems.set(name, child);
                    return true;
                }
                if (itemsWithSameName instanceof Array) {
                    for (var _i = 0, itemsWithSameName_1 = itemsWithSameName; _i < itemsWithSameName_1.length; _i++) {
                        var itemWithSameName = itemsWithSameName_1[_i];
                        if (tryMerge(itemWithSameName, child)) {
                            return false;
                        }
                    }
                    itemsWithSameName.push(child);
                    return true;
                }
                else {
                    var itemWithSameName = itemsWithSameName;
                    if (tryMerge(itemWithSameName, child)) {
                        return false;
                    }
                    nameToItems.set(name, [itemWithSameName, child]);
                    return true;
                }
                function tryMerge(a, b) {
                    if (shouldReallyMerge(a.node, b.node)) {
                        merge(a, b);
                        return true;
                    }
                    return false;
                }
            });
            /** a and b have the same name, but they may not be mergeable. */
            function shouldReallyMerge(a, b) {
                return a.kind === b.kind && (a.kind !== 233 /* ModuleDeclaration */ || areSameModule(a, b));
                // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes.
                // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'!
                function areSameModule(a, b) {
                    if (a.body.kind !== b.body.kind) {
                        return false;
                    }
                    if (a.body.kind !== 233 /* ModuleDeclaration */) {
                        return true;
                    }
                    return areSameModule(a.body, b.body);
                }
            }
            /** Merge source into target. Source should be thrown away after this is called. */
            function merge(target, source) {
                target.additionalNodes = target.additionalNodes || [];
                target.additionalNodes.push(source.node);
                if (source.additionalNodes) {
                    (_a = target.additionalNodes).push.apply(_a, source.additionalNodes);
                }
                target.children = ts.concatenate(target.children, source.children);
                if (target.children) {
                    mergeChildren(target.children);
                    sortChildren(target.children);
                }
                var _a;
            }
        }
        /** Recursively ensure that each NavNode's children are in sorted order. */
        function sortChildren(children) {
            children.sort(compareChildren);
        }
        function compareChildren(child1, child2) {
            var name1 = tryGetName(child1.node), name2 = tryGetName(child2.node);
            if (name1 && name2) {
                var cmp = ts.compareStringsCaseInsensitive(name1, name2);
                return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
            }
            else {
                return name1 ? 1 : name2 ? -1 : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
            }
        }
        /**
         * This differs from getItemName because this is just used for sorting.
         * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.
         * So `new()` can still come before an `aardvark` method.
         */
        function tryGetName(node) {
            if (node.kind === 233 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            var declName = ts.getNameOfDeclaration(node);
            if (declName) {
                return ts.unescapeLeadingUnderscores(ts.getPropertyNameForPropertyNameNode(declName));
            }
            switch (node.kind) {
                case 186 /* FunctionExpression */:
                case 187 /* ArrowFunction */:
                case 199 /* ClassExpression */:
                    return getFunctionOrClassName(node);
                case 283 /* JSDocTypedefTag */:
                    return getJSDocTypedefTagName(node);
                default:
                    return undefined;
            }
        }
        function getItemName(node) {
            if (node.kind === 233 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            var name = ts.getNameOfDeclaration(node);
            if (name) {
                var text = nodeText(name);
                if (text.length > 0) {
                    return text;
                }
            }
            switch (node.kind) {
                case 265 /* SourceFile */:
                    var sourceFile = node;
                    return ts.isExternalModule(sourceFile)
                        ? "\"" + ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName)))) + "\""
                        : "<global>";
                case 187 /* ArrowFunction */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 229 /* ClassDeclaration */:
                case 199 /* ClassExpression */:
                    if (ts.getModifierFlags(node) & 512 /* Default */) {
                        return "default";
                    }
                    // We may get a string with newlines or other whitespace in the case of an object dereference
                    // (eg: "app\n.onactivated"), so we should remove the whitespace for readabiltiy in the
                    // navigation bar.
                    return getFunctionOrClassName(node);
                case 152 /* Constructor */:
                    return "constructor";
                case 156 /* ConstructSignature */:
                    return "new()";
                case 155 /* CallSignature */:
                    return "()";
                case 157 /* IndexSignature */:
                    return "[]";
                case 283 /* JSDocTypedefTag */:
                    return getJSDocTypedefTagName(node);
                default:
                    return "<unknown>";
            }
        }
        function getJSDocTypedefTagName(node) {
            if (node.name) {
                return node.name.text;
            }
            else {
                var parentNode = node.parent && node.parent.parent;
                if (parentNode && parentNode.kind === 208 /* VariableStatement */) {
                    if (parentNode.declarationList.declarations.length > 0) {
                        var nameIdentifier = parentNode.declarationList.declarations[0].name;
                        if (nameIdentifier.kind === 71 /* Identifier */) {
                            return nameIdentifier.text;
                        }
                    }
                }
                return "<typedef>";
            }
        }
        /** Flattens the NavNode tree to a list, keeping only the top-level items. */
        function topLevelItems(root) {
            var topLevel = [];
            function recur(item) {
                if (isTopLevel(item)) {
                    topLevel.push(item);
                    if (item.children) {
                        for (var _i = 0, _a = item.children; _i < _a.length; _i++) {
                            var child = _a[_i];
                            recur(child);
                        }
                    }
                }
            }
            recur(root);
            return topLevel;
            function isTopLevel(item) {
                switch (navigationBarNodeKind(item)) {
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 232 /* EnumDeclaration */:
                    case 230 /* InterfaceDeclaration */:
                    case 233 /* ModuleDeclaration */:
                    case 265 /* SourceFile */:
                    case 231 /* TypeAliasDeclaration */:
                    case 283 /* JSDocTypedefTag */:
                        return true;
                    case 152 /* Constructor */:
                    case 151 /* MethodDeclaration */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    case 226 /* VariableDeclaration */:
                        return hasSomeImportantChild(item);
                    case 187 /* ArrowFunction */:
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                        return isTopLevelFunctionDeclaration(item);
                    default:
                        return false;
                }
                function isTopLevelFunctionDeclaration(item) {
                    if (!item.node.body) {
                        return false;
                    }
                    switch (navigationBarNodeKind(item.parent)) {
                        case 234 /* ModuleBlock */:
                        case 265 /* SourceFile */:
                        case 151 /* MethodDeclaration */:
                        case 152 /* Constructor */:
                            return true;
                        default:
                            return hasSomeImportantChild(item);
                    }
                }
                function hasSomeImportantChild(item) {
                    return ts.forEach(item.children, function (child) {
                        var childKind = navigationBarNodeKind(child);
                        return childKind !== 226 /* VariableDeclaration */ && childKind !== 176 /* BindingElement */;
                    });
                }
            }
        }
        function convertToTree(n) {
            return {
                text: getItemName(n.node),
                kind: ts.getNodeKind(n.node),
                kindModifiers: getModifiers(n.node),
                spans: getSpans(n),
                childItems: ts.map(n.children, convertToTree)
            };
        }
        function convertToTopLevelItem(n) {
            return {
                text: getItemName(n.node),
                kind: ts.getNodeKind(n.node),
                kindModifiers: getModifiers(n.node),
                spans: getSpans(n),
                childItems: ts.map(n.children, convertToChildItem) || emptyChildItemArray,
                indent: n.indent,
                bolded: false,
                grayed: false
            };
            function convertToChildItem(n) {
                return {
                    text: getItemName(n.node),
                    kind: ts.getNodeKind(n.node),
                    kindModifiers: ts.getNodeModifiers(n.node),
                    spans: getSpans(n),
                    childItems: emptyChildItemArray,
                    indent: 0,
                    bolded: false,
                    grayed: false
                };
            }
        }
        function getSpans(n) {
            var spans = [getNodeSpan(n.node)];
            if (n.additionalNodes) {
                for (var _i = 0, _a = n.additionalNodes; _i < _a.length; _i++) {
                    var node = _a[_i];
                    spans.push(getNodeSpan(node));
                }
            }
            return spans;
        }
        function getModuleName(moduleDeclaration) {
            // We want to maintain quotation marks.
            if (ts.isAmbientModule(moduleDeclaration)) {
                return ts.getTextOfNode(moduleDeclaration.name);
            }
            // Otherwise, we need to aggregate each identifier to build up the qualified name.
            var result = [];
            result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
            while (moduleDeclaration.body && moduleDeclaration.body.kind === 233 /* ModuleDeclaration */) {
                moduleDeclaration = moduleDeclaration.body;
                result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
            }
            return result.join(".");
        }
        /**
         * For 'module A.B.C', we want to get the node for 'C'.
         * We store 'A' as associated with a NavNode, and use getModuleName to traverse down again.
         */
        function getInteriorModule(decl) {
            return decl.body.kind === 233 /* ModuleDeclaration */ ? getInteriorModule(decl.body) : decl;
        }
        function isComputedProperty(member) {
            return !member.name || member.name.kind === 144 /* ComputedPropertyName */;
        }
        function getNodeSpan(node) {
            return node.kind === 265 /* SourceFile */
                ? ts.createTextSpanFromBounds(node.getFullStart(), node.getEnd())
                : ts.createTextSpanFromNode(node, curSourceFile);
        }
        function getModifiers(node) {
            if (node.parent && node.parent.kind === 226 /* VariableDeclaration */) {
                node = node.parent;
            }
            return ts.getNodeModifiers(node);
        }
        function getFunctionOrClassName(node) {
            if (node.name && ts.getFullWidth(node.name) > 0) {
                return ts.declarationNameToString(node.name);
            }
            else if (node.parent.kind === 226 /* VariableDeclaration */) {
                return ts.declarationNameToString(node.parent.name);
            }
            else if (node.parent.kind === 194 /* BinaryExpression */ &&
                node.parent.operatorToken.kind === 58 /* EqualsToken */) {
                return nodeText(node.parent.left).replace(whiteSpaceRegex, "");
            }
            else if (node.parent.kind === 261 /* PropertyAssignment */ && node.parent.name) {
                return nodeText(node.parent.name);
            }
            else if (ts.getModifierFlags(node) & 512 /* Default */) {
                return "default";
            }
            else {
                return ts.isClassLike(node) ? "<class>" : "<function>";
            }
        }
        function isFunctionOrClassExpression(node) {
            switch (node.kind) {
                case 187 /* ArrowFunction */:
                case 186 /* FunctionExpression */:
                case 199 /* ClassExpression */:
                    return true;
                default:
                    return false;
            }
        }
    })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var OutliningElementsCollector;
    (function (OutliningElementsCollector) {
        var collapseText = "...";
        var maxDepth = 40;
        var defaultLabel = "#region";
        var regionMatch = new RegExp("^\\s*//\\s*#(end)?region(?:\\s+(.*))?$");
        function collectElements(sourceFile, cancellationToken) {
            var elements = [];
            var depth = 0;
            var regions = [];
            walk(sourceFile);
            gatherRegions();
            return elements.sort(function (span1, span2) { return span1.textSpan.start - span2.textSpan.start; });
            /** If useFullStart is true, then the collapsing span includes leading whitespace, including linebreaks. */
            function addOutliningSpan(hintSpanNode, startElement, endElement, autoCollapse, useFullStart) {
                if (hintSpanNode && startElement && endElement) {
                    var span_13 = {
                        textSpan: ts.createTextSpanFromBounds(useFullStart ? startElement.getFullStart() : startElement.getStart(), endElement.getEnd()),
                        hintSpan: ts.createTextSpanFromNode(hintSpanNode, sourceFile),
                        bannerText: collapseText,
                        autoCollapse: autoCollapse,
                    };
                    elements.push(span_13);
                }
            }
            function addOutliningSpanComments(commentSpan, autoCollapse) {
                if (commentSpan) {
                    var span_14 = {
                        textSpan: ts.createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
                        hintSpan: ts.createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
                        bannerText: collapseText,
                        autoCollapse: autoCollapse,
                    };
                    elements.push(span_14);
                }
            }
            function addOutliningForLeadingCommentsForNode(n) {
                var comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
                if (comments) {
                    var firstSingleLineCommentStart = -1;
                    var lastSingleLineCommentEnd = -1;
                    var isFirstSingleLineComment = true;
                    var singleLineCommentCount = 0;
                    for (var _i = 0, comments_3 = comments; _i < comments_3.length; _i++) {
                        var currentComment = comments_3[_i];
                        cancellationToken.throwIfCancellationRequested();
                        // For single line comments, combine consecutive ones (2 or more) into
                        // a single span from the start of the first till the end of the last
                        if (currentComment.kind === 2 /* SingleLineCommentTrivia */) {
                            if (isFirstSingleLineComment) {
                                firstSingleLineCommentStart = currentComment.pos;
                            }
                            isFirstSingleLineComment = false;
                            lastSingleLineCommentEnd = currentComment.end;
                            singleLineCommentCount++;
                        }
                        else if (currentComment.kind === 3 /* MultiLineCommentTrivia */) {
                            combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
                            addOutliningSpanComments(currentComment, /*autoCollapse*/ false);
                            singleLineCommentCount = 0;
                            lastSingleLineCommentEnd = -1;
                            isFirstSingleLineComment = true;
                        }
                    }
                    combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
                }
            }
            function combineAndAddMultipleSingleLineComments(count, start, end) {
                // Only outline spans of two or more consecutive single line comments
                if (count > 1) {
                    var multipleSingleLineComments = {
                        kind: 2 /* SingleLineCommentTrivia */,
                        pos: start,
                        end: end,
                    };
                    addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
                }
            }
            function autoCollapse(node) {
                return ts.isFunctionBlock(node) && node.parent.kind !== 187 /* ArrowFunction */;
            }
            function gatherRegions() {
                var lineStarts = sourceFile.getLineStarts();
                for (var i = 0; i < lineStarts.length; i++) {
                    var currentLineStart = lineStarts[i];
                    var lineEnd = lineStarts[i + 1] - 1 || sourceFile.getEnd();
                    var comment = sourceFile.text.substring(currentLineStart, lineEnd);
                    var result = comment.match(regionMatch);
                    if (result && !ts.isInComment(sourceFile, currentLineStart)) {
                        if (!result[1]) {
                            var start = sourceFile.getFullText().indexOf("//", currentLineStart);
                            var textSpan = ts.createTextSpanFromBounds(start, lineEnd);
                            var region = {
                                textSpan: textSpan,
                                hintSpan: textSpan,
                                bannerText: result[2] || defaultLabel,
                                autoCollapse: false
                            };
                            regions.push(region);
                        }
                        else {
                            var region = regions.pop();
                            if (region) {
                                region.textSpan.length = lineEnd - region.textSpan.start;
                                region.hintSpan.length = lineEnd - region.textSpan.start;
                                elements.push(region);
                            }
                        }
                    }
                }
            }
            function walk(n) {
                cancellationToken.throwIfCancellationRequested();
                if (depth > maxDepth) {
                    return;
                }
                if (ts.isDeclaration(n)) {
                    addOutliningForLeadingCommentsForNode(n);
                }
                switch (n.kind) {
                    case 207 /* Block */:
                        if (!ts.isFunctionBlock(n)) {
                            var parent = n.parent;
                            var openBrace_1 = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
                            var closeBrace_1 = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
                            // Check if the block is standalone, or 'attached' to some parent statement.
                            // If the latter, we want to collapse the block, but consider its hint span
                            // to be the entire span of the parent.
                            if (parent.kind === 212 /* DoStatement */ ||
                                parent.kind === 215 /* ForInStatement */ ||
                                parent.kind === 216 /* ForOfStatement */ ||
                                parent.kind === 214 /* ForStatement */ ||
                                parent.kind === 211 /* IfStatement */ ||
                                parent.kind === 213 /* WhileStatement */ ||
                                parent.kind === 220 /* WithStatement */ ||
                                parent.kind === 260 /* CatchClause */) {
                                addOutliningSpan(parent, openBrace_1, closeBrace_1, autoCollapse(n), /*useFullStart*/ true);
                                break;
                            }
                            if (parent.kind === 224 /* TryStatement */) {
                                // Could be the try-block, or the finally-block.
                                var tryStatement = parent;
                                if (tryStatement.tryBlock === n) {
                                    addOutliningSpan(parent, openBrace_1, closeBrace_1, autoCollapse(n), /*useFullStart*/ true);
                                    break;
                                }
                                else if (tryStatement.finallyBlock === n) {
                                    var finallyKeyword = ts.findChildOfKind(tryStatement, 87 /* FinallyKeyword */, sourceFile);
                                    if (finallyKeyword) {
                                        addOutliningSpan(finallyKeyword, openBrace_1, closeBrace_1, autoCollapse(n), /*useFullStart*/ true);
                                        break;
                                    }
                                }
                                // fall through.
                            }
                            // Block was a standalone block.  In this case we want to only collapse
                            // the span of the block, independent of any parent span.
                            var span_15 = ts.createTextSpanFromNode(n);
                            elements.push({
                                textSpan: span_15,
                                hintSpan: span_15,
                                bannerText: collapseText,
                                autoCollapse: autoCollapse(n)
                            });
                            break;
                        }
                    // falls through
                    case 234 /* ModuleBlock */: {
                        var openBrace_2 = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
                        var closeBrace_2 = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
                        addOutliningSpan(n.parent, openBrace_2, closeBrace_2, autoCollapse(n), /*useFullStart*/ true);
                        break;
                    }
                    case 229 /* ClassDeclaration */:
                    case 230 /* InterfaceDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 235 /* CaseBlock */: {
                        var openBrace_3 = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
                        var closeBrace_3 = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
                        addOutliningSpan(n, openBrace_3, closeBrace_3, autoCollapse(n), /*useFullStart*/ true);
                        break;
                    }
                    // If the block has no leading keywords and is inside an array literal,
                    // we only want to collapse the span of the block.
                    // Otherwise, the collapsed section will include the end of the previous line.
                    case 178 /* ObjectLiteralExpression */:
                        var openBrace = ts.findChildOfKind(n, 17 /* OpenBraceToken */, sourceFile);
                        var closeBrace = ts.findChildOfKind(n, 18 /* CloseBraceToken */, sourceFile);
                        addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n), /*useFullStart*/ !ts.isArrayLiteralExpression(n.parent));
                        break;
                    case 177 /* ArrayLiteralExpression */:
                        var openBracket = ts.findChildOfKind(n, 21 /* OpenBracketToken */, sourceFile);
                        var closeBracket = ts.findChildOfKind(n, 22 /* CloseBracketToken */, sourceFile);
                        addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n), /*useFullStart*/ !ts.isArrayLiteralExpression(n.parent));
                        break;
                }
                depth++;
                ts.forEachChild(n, walk);
                depth--;
            }
        }
        OutliningElementsCollector.collectElements = collectElements;
    })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
    var PatternMatchKind;
    (function (PatternMatchKind) {
        PatternMatchKind[PatternMatchKind["exact"] = 0] = "exact";
        PatternMatchKind[PatternMatchKind["prefix"] = 1] = "prefix";
        PatternMatchKind[PatternMatchKind["substring"] = 2] = "substring";
        PatternMatchKind[PatternMatchKind["camelCase"] = 3] = "camelCase";
    })(PatternMatchKind = ts.PatternMatchKind || (ts.PatternMatchKind = {}));
    function createPatternMatch(kind, punctuationStripped, isCaseSensitive, camelCaseWeight) {
        return {
            kind: kind,
            punctuationStripped: punctuationStripped,
            isCaseSensitive: isCaseSensitive,
            camelCaseWeight: camelCaseWeight
        };
    }
    function createPatternMatcher(pattern) {
        // We'll often see the same candidate string many times when searching (For example, when
        // we see the name of a module that is used everywhere, or the name of an overload).  As
        // such, we cache the information we compute about the candidate for the life of this
        // pattern matcher so we don't have to compute it multiple times.
        var stringToWordSpans = ts.createMap();
        pattern = pattern.trim();
        var dotSeparatedSegments = pattern.split(".").map(function (p) { return createSegment(p.trim()); });
        var invalidPattern = dotSeparatedSegments.length === 0 || ts.forEach(dotSeparatedSegments, segmentIsInvalid);
        return {
            getMatches: getMatches,
            getMatchesForLastSegmentOfPattern: getMatchesForLastSegmentOfPattern,
            patternContainsDots: dotSeparatedSegments.length > 1
        };
        // Quick checks so we can bail out when asked to match a candidate.
        function skipMatch(candidate) {
            return invalidPattern || !candidate;
        }
        function getMatchesForLastSegmentOfPattern(candidate) {
            if (skipMatch(candidate)) {
                return undefined;
            }
            return matchSegment(candidate, ts.lastOrUndefined(dotSeparatedSegments));
        }
        function getMatches(candidateContainers, candidate) {
            if (skipMatch(candidate)) {
                return undefined;
            }
            // First, check that the last part of the dot separated pattern matches the name of the
            // candidate.  If not, then there's no point in proceeding and doing the more
            // expensive work.
            var candidateMatch = matchSegment(candidate, ts.lastOrUndefined(dotSeparatedSegments));
            if (!candidateMatch) {
                return undefined;
            }
            candidateContainers = candidateContainers || [];
            // -1 because the last part was checked against the name, and only the rest
            // of the parts are checked against the container.
            if (dotSeparatedSegments.length - 1 > candidateContainers.length) {
                // There weren't enough container parts to match against the pattern parts.
                // So this definitely doesn't match.
                return undefined;
            }
            // So far so good.  Now break up the container for the candidate and check if all
            // the dotted parts match up correctly.
            var totalMatch = candidateMatch;
            for (var i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i -= 1, j -= 1) {
                var segment = dotSeparatedSegments[i];
                var containerName = candidateContainers[j];
                var containerMatch = matchSegment(containerName, segment);
                if (!containerMatch) {
                    // This container didn't match the pattern piece.  So there's no match at all.
                    return undefined;
                }
                ts.addRange(totalMatch, containerMatch);
            }
            // Success, this symbol's full name matched against the dotted name the user was asking
            // about.
            return totalMatch;
        }
        function getWordSpans(word) {
            var spans = stringToWordSpans.get(word);
            if (!spans) {
                stringToWordSpans.set(word, spans = breakIntoWordSpans(word));
            }
            return spans;
        }
        function matchTextChunk(candidate, chunk, punctuationStripped) {
            var index = indexOfIgnoringCase(candidate, chunk.textLowerCase);
            if (index === 0) {
                if (chunk.text.length === candidate.length) {
                    // a) Check if the part matches the candidate entirely, in an case insensitive or
                    //    sensitive manner.  If it does, return that there was an exact match.
                    return createPatternMatch(PatternMatchKind.exact, punctuationStripped, /*isCaseSensitive:*/ candidate === chunk.text);
                }
                else {
                    // b) Check if the part is a prefix of the candidate, in a case insensitive or sensitive
                    //    manner.  If it does, return that there was a prefix match.
                    return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text));
                }
            }
            var isLowercase = chunk.isLowerCase;
            if (isLowercase) {
                if (index > 0) {
                    // c) If the part is entirely lowercase, then check if it is contained anywhere in the
                    //    candidate in a case insensitive manner.  If so, return that there was a substring
                    //    match.
                    //
                    //    Note: We only have a substring match if the lowercase part is prefix match of some
                    //    word part. That way we don't match something like 'Class' when the user types 'a'.
                    //    But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
                    var wordSpans = getWordSpans(candidate);
                    for (var _i = 0, wordSpans_1 = wordSpans; _i < wordSpans_1.length; _i++) {
                        var span_16 = wordSpans_1[_i];
                        if (partStartsWith(candidate, span_16, chunk.text, /*ignoreCase:*/ true)) {
                            return createPatternMatch(PatternMatchKind.substring, punctuationStripped, 
                            /*isCaseSensitive:*/ partStartsWith(candidate, span_16, chunk.text, /*ignoreCase:*/ false));
                        }
                    }
                }
            }
            else {
                // d) If the part was not entirely lowercase, then check if it is contained in the
                //    candidate in a case *sensitive* manner. If so, return that there was a substring
                //    match.
                if (candidate.indexOf(chunk.text) > 0) {
                    return createPatternMatch(PatternMatchKind.substring, punctuationStripped, /*isCaseSensitive:*/ true);
                }
            }
            if (!isLowercase) {
                // e) If the part was not entirely lowercase, then attempt a camel cased match as well.
                if (chunk.characterSpans.length > 0) {
                    var candidateParts = getWordSpans(candidate);
                    var camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false);
                    if (camelCaseWeight !== undefined) {
                        return createPatternMatch(PatternMatchKind.camelCase, punctuationStripped, /*isCaseSensitive:*/ true, /*camelCaseWeight:*/ camelCaseWeight);
                    }
                    camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ true);
                    if (camelCaseWeight !== undefined) {
                        return createPatternMatch(PatternMatchKind.camelCase, punctuationStripped, /*isCaseSensitive:*/ false, /*camelCaseWeight:*/ camelCaseWeight);
                    }
                }
            }
            if (isLowercase) {
                // f) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
                // We could check every character boundary start of the candidate for the pattern. However, that's
                // an m * n operation in the wost case. Instead, find the first instance of the pattern
                // substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
                // filter the list based on a substring that starts on a capital letter and also with a lowercase one.
                // (Pattern: fogbar, Candidate: quuxfogbarFogBar).
                if (chunk.text.length < candidate.length) {
                    if (index > 0 && isUpperCaseLetter(candidate.charCodeAt(index))) {
                        return createPatternMatch(PatternMatchKind.substring, punctuationStripped, /*isCaseSensitive:*/ false);
                    }
                }
            }
            return undefined;
        }
        function containsSpaceOrAsterisk(text) {
            for (var i = 0; i < text.length; i++) {
                var ch = text.charCodeAt(i);
                if (ch === 32 /* space */ || ch === 42 /* asterisk */) {
                    return true;
                }
            }
            return false;
        }
        function matchSegment(candidate, segment) {
            // First check if the segment matches as is.  This is also useful if the segment contains
            // characters we would normally strip when splitting into parts that we also may want to
            // match in the candidate.  For example if the segment is "@int" and the candidate is
            // "@int", then that will show up as an exact match here.
            //
            // Note: if the segment contains a space or an asterisk then we must assume that it's a
            // multi-word segment.
            if (!containsSpaceOrAsterisk(segment.totalTextChunk.text)) {
                var match = matchTextChunk(candidate, segment.totalTextChunk, /*punctuationStripped:*/ false);
                if (match) {
                    return [match];
                }
            }
            // The logic for pattern matching is now as follows:
            //
            // 1) Break the segment passed in into words.  Breaking is rather simple and a
            //    good way to think about it that if gives you all the individual alphanumeric words
            //    of the pattern.
            //
            // 2) For each word try to match the word against the candidate value.
            //
            // 3) Matching is as follows:
            //
            //   a) Check if the word matches the candidate entirely, in an case insensitive or
            //    sensitive manner.  If it does, return that there was an exact match.
            //
            //   b) Check if the word is a prefix of the candidate, in a case insensitive or
            //      sensitive manner.  If it does, return that there was a prefix match.
            //
            //   c) If the word is entirely lowercase, then check if it is contained anywhere in the
            //      candidate in a case insensitive manner.  If so, return that there was a substring
            //      match.
            //
            //      Note: We only have a substring match if the lowercase part is prefix match of
            //      some word part. That way we don't match something like 'Class' when the user
            //      types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
            //      'a').
            //
            //   d) If the word was not entirely lowercase, then check if it is contained in the
            //      candidate in a case *sensitive* manner. If so, return that there was a substring
            //      match.
            //
            //   e) If the word was not entirely lowercase, then attempt a camel cased match as
            //      well.
            //
            //   f) The word is all lower case. Is it a case insensitive substring of the candidate starting
            //      on a part boundary of the candidate?
            //
            // Only if all words have some sort of match is the pattern considered matched.
            var subWordTextChunks = segment.subWordTextChunks;
            var matches = undefined;
            for (var _i = 0, subWordTextChunks_1 = subWordTextChunks; _i < subWordTextChunks_1.length; _i++) {
                var subWordTextChunk = subWordTextChunks_1[_i];
                // Try to match the candidate with this word
                var result = matchTextChunk(candidate, subWordTextChunk, /*punctuationStripped:*/ true);
                if (!result) {
                    return undefined;
                }
                matches = matches || [];
                matches.push(result);
            }
            return matches;
        }
        function partStartsWith(candidate, candidateSpan, pattern, ignoreCase, patternSpan) {
            var patternPartStart = patternSpan ? patternSpan.start : 0;
            var patternPartLength = patternSpan ? patternSpan.length : pattern.length;
            if (patternPartLength > candidateSpan.length) {
                // Pattern part is longer than the candidate part. There can never be a match.
                return false;
            }
            if (ignoreCase) {
                for (var i = 0; i < patternPartLength; i++) {
                    var ch1 = pattern.charCodeAt(patternPartStart + i);
                    var ch2 = candidate.charCodeAt(candidateSpan.start + i);
                    if (toLowerCase(ch1) !== toLowerCase(ch2)) {
                        return false;
                    }
                }
            }
            else {
                for (var i = 0; i < patternPartLength; i++) {
                    var ch1 = pattern.charCodeAt(patternPartStart + i);
                    var ch2 = candidate.charCodeAt(candidateSpan.start + i);
                    if (ch1 !== ch2) {
                        return false;
                    }
                }
            }
            return true;
        }
        function tryCamelCaseMatch(candidate, candidateParts, chunk, ignoreCase) {
            var chunkCharacterSpans = chunk.characterSpans;
            // Note: we may have more pattern parts than candidate parts.  This is because multiple
            // pattern parts may match a candidate part.  For example "SiUI" against "SimpleUI".
            // We'll have 3 pattern parts Si/U/I against two candidate parts Simple/UI.  However, U
            // and I will both match in UI.
            var currentCandidate = 0;
            var currentChunkSpan = 0;
            var firstMatch = undefined;
            var contiguous = undefined;
            while (true) {
                // Let's consider our termination cases
                if (currentChunkSpan === chunkCharacterSpans.length) {
                    // We did match! We shall assign a weight to this
                    var weight = 0;
                    // Was this contiguous?
                    if (contiguous) {
                        weight += 1;
                    }
                    // Did we start at the beginning of the candidate?
                    if (firstMatch === 0) {
                        weight += 2;
                    }
                    return weight;
                }
                else if (currentCandidate === candidateParts.length) {
                    // No match, since we still have more of the pattern to hit
                    return undefined;
                }
                var candidatePart = candidateParts[currentCandidate];
                var gotOneMatchThisCandidate = false;
                // Consider the case of matching SiUI against SimpleUIElement. The candidate parts
                // will be Simple/UI/Element, and the pattern parts will be Si/U/I.  We'll match 'Si'
                // against 'Simple' first.  Then we'll match 'U' against 'UI'. However, we want to
                // still keep matching pattern parts against that candidate part.
                for (; currentChunkSpan < chunkCharacterSpans.length; currentChunkSpan++) {
                    var chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan];
                    if (gotOneMatchThisCandidate) {
                        // We've already gotten one pattern part match in this candidate.  We will
                        // only continue trying to consumer pattern parts if the last part and this
                        // part are both upper case.
                        if (!isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan - 1].start)) ||
                            !isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan].start))) {
                            break;
                        }
                    }
                    if (!partStartsWith(candidate, candidatePart, chunk.text, ignoreCase, chunkCharacterSpan)) {
                        break;
                    }
                    gotOneMatchThisCandidate = true;
                    firstMatch = firstMatch === undefined ? currentCandidate : firstMatch;
                    // If we were contiguous, then keep that value.  If we weren't, then keep that
                    // value.  If we don't know, then set the value to 'true' as an initial match is
                    // obviously contiguous.
                    contiguous = contiguous === undefined ? true : contiguous;
                    candidatePart = ts.createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length);
                }
                // Check if we matched anything at all.  If we didn't, then we need to unset the
                // contiguous bit if we currently had it set.
                // If we haven't set the bit yet, then that means we haven't matched anything so
                // far, and we don't want to change that.
                if (!gotOneMatchThisCandidate && contiguous !== undefined) {
                    contiguous = false;
                }
                // Move onto the next candidate.
                currentCandidate++;
            }
        }
    }
    ts.createPatternMatcher = createPatternMatcher;
    function createSegment(text) {
        return {
            totalTextChunk: createTextChunk(text),
            subWordTextChunks: breakPatternIntoTextChunks(text)
        };
    }
    // A segment is considered invalid if we couldn't find any words in it.
    function segmentIsInvalid(segment) {
        return segment.subWordTextChunks.length === 0;
    }
    function isUpperCaseLetter(ch) {
        // Fast check for the ascii range.
        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
            return true;
        }
        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 5 /* Latest */)) {
            return false;
        }
        // TODO: find a way to determine this for any unicode characters in a
        // non-allocating manner.
        var str = String.fromCharCode(ch);
        return str === str.toUpperCase();
    }
    function isLowerCaseLetter(ch) {
        // Fast check for the ascii range.
        if (ch >= 97 /* a */ && ch <= 122 /* z */) {
            return true;
        }
        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 5 /* Latest */)) {
            return false;
        }
        // TODO: find a way to determine this for any unicode characters in a
        // non-allocating manner.
        var str = String.fromCharCode(ch);
        return str === str.toLowerCase();
    }
    // Assumes 'value' is already lowercase.
    function indexOfIgnoringCase(string, value) {
        var n = string.length - value.length;
        for (var i = 0; i <= n; i++) {
            if (startsWithIgnoringCase(string, value, i)) {
                return i;
            }
        }
        return -1;
    }
    // Assumes 'value' is already lowercase.
    function startsWithIgnoringCase(string, value, start) {
        for (var i = 0; i < value.length; i++) {
            var ch1 = toLowerCase(string.charCodeAt(i + start));
            var ch2 = value.charCodeAt(i);
            if (ch1 !== ch2) {
                return false;
            }
        }
        return true;
    }
    function toLowerCase(ch) {
        // Fast convert for the ascii range.
        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
            return 97 /* a */ + (ch - 65 /* A */);
        }
        if (ch < 127 /* maxAsciiCharacter */) {
            return ch;
        }
        // TODO: find a way to compute this for any unicode characters in a
        // non-allocating manner.
        return String.fromCharCode(ch).toLowerCase().charCodeAt(0);
    }
    function isDigit(ch) {
        // TODO(cyrusn): Find a way to support this for unicode digits.
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    function isWordChar(ch) {
        return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === 95 /* _ */ || ch === 36 /* $ */;
    }
    function breakPatternIntoTextChunks(pattern) {
        var result = [];
        var wordStart = 0;
        var wordLength = 0;
        for (var i = 0; i < pattern.length; i++) {
            var ch = pattern.charCodeAt(i);
            if (isWordChar(ch)) {
                if (wordLength === 0) {
                    wordStart = i;
                }
                wordLength++;
            }
            else {
                if (wordLength > 0) {
                    result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
                    wordLength = 0;
                }
            }
        }
        if (wordLength > 0) {
            result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
        }
        return result;
    }
    function createTextChunk(text) {
        var textLowerCase = text.toLowerCase();
        return {
            text: text,
            textLowerCase: textLowerCase,
            isLowerCase: text === textLowerCase,
            characterSpans: breakIntoCharacterSpans(text)
        };
    }
    /* @internal */ function breakIntoCharacterSpans(identifier) {
        return breakIntoSpans(identifier, /*word:*/ false);
    }
    ts.breakIntoCharacterSpans = breakIntoCharacterSpans;
    /* @internal */ function breakIntoWordSpans(identifier) {
        return breakIntoSpans(identifier, /*word:*/ true);
    }
    ts.breakIntoWordSpans = breakIntoWordSpans;
    function breakIntoSpans(identifier, word) {
        var result = [];
        var wordStart = 0;
        for (var i = 1; i < identifier.length; i++) {
            var lastIsDigit = isDigit(identifier.charCodeAt(i - 1));
            var currentIsDigit = isDigit(identifier.charCodeAt(i));
            var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i);
            var hasTransitionFromUpperToLower = transitionFromUpperToLower(identifier, word, i, wordStart);
            if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
                charIsPunctuation(identifier.charCodeAt(i)) ||
                lastIsDigit !== currentIsDigit ||
                hasTransitionFromLowerToUpper ||
                hasTransitionFromUpperToLower) {
                if (!isAllPunctuation(identifier, wordStart, i)) {
                    result.push(ts.createTextSpan(wordStart, i - wordStart));
                }
                wordStart = i;
            }
        }
        if (!isAllPunctuation(identifier, wordStart, identifier.length)) {
            result.push(ts.createTextSpan(wordStart, identifier.length - wordStart));
        }
        return result;
    }
    function charIsPunctuation(ch) {
        switch (ch) {
            case 33 /* exclamation */:
            case 34 /* doubleQuote */:
            case 35 /* hash */:
            case 37 /* percent */:
            case 38 /* ampersand */:
            case 39 /* singleQuote */:
            case 40 /* openParen */:
            case 41 /* closeParen */:
            case 42 /* asterisk */:
            case 44 /* comma */:
            case 45 /* minus */:
            case 46 /* dot */:
            case 47 /* slash */:
            case 58 /* colon */:
            case 59 /* semicolon */:
            case 63 /* question */:
            case 64 /* at */:
            case 91 /* openBracket */:
            case 92 /* backslash */:
            case 93 /* closeBracket */:
            case 95 /* _ */:
            case 123 /* openBrace */:
            case 125 /* closeBrace */:
                return true;
        }
        return false;
    }
    function isAllPunctuation(identifier, start, end) {
        for (var i = start; i < end; i++) {
            var ch = identifier.charCodeAt(i);
            // We don't consider _ or $ as punctuation as there may be things with that name.
            if (!charIsPunctuation(ch) || ch === 95 /* _ */ || ch === 36 /* $ */) {
                return false;
            }
        }
        return true;
    }
    function transitionFromUpperToLower(identifier, word, index, wordStart) {
        if (word) {
            // Cases this supports:
            // 1) IDisposable -> I, Disposable
            // 2) UIElement -> UI, Element
            // 3) HTMLDocument -> HTML, Document
            //
            // etc.
            if (index !== wordStart &&
                index + 1 < identifier.length) {
                var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
                var nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1));
                if (currentIsUpper && nextIsLower) {
                    // We have a transition from an upper to a lower letter here.  But we only
                    // want to break if all the letters that preceded are uppercase.  i.e. if we
                    // have "Foo" we don't want to break that into "F, oo".  But if we have
                    // "IFoo" or "UIFoo", then we want to break that into "I, Foo" and "UI,
                    // Foo".  i.e. the last uppercase letter belongs to the lowercase letters
                    // that follows.  Note: this will make the following not split properly:
                    // "HELLOthere".  However, these sorts of names do not show up in .Net
                    // programs.
                    for (var i = wordStart; i < index; i++) {
                        if (!isUpperCaseLetter(identifier.charCodeAt(i))) {
                            return false;
                        }
                    }
                    return true;
                }
            }
        }
        return false;
    }
    function transitionFromLowerToUpper(identifier, word, index) {
        var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1));
        var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
        // See if the casing indicates we're starting a new word. Note: if we're breaking on
        // words, then just seeing an upper case character isn't enough.  Instead, it has to
        // be uppercase and the previous character can't be uppercase.
        //
        // For example, breaking "AddMetadata" on words would make: Add Metadata
        //
        // on characters would be: A dd M etadata
        //
        // Break "AM" on words would be: AM
        //
        // on characters would be: A M
        //
        // We break the search string on characters.  But we break the symbol name on words.
        var transition = word
            ? (currentIsUpper && !lastIsUpper)
            : currentIsUpper;
        return transition;
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
        if (readImportFiles === void 0) { readImportFiles = true; }
        if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
        var referencedFiles = [];
        var typeReferenceDirectives = [];
        var importedFiles = [];
        var ambientExternalModules;
        var isNoDefaultLib = false;
        var braceNesting = 0;
        // assume that text represent an external module if it contains at least one top level import/export
        // ambient modules that are found inside external modules are interpreted as module augmentations
        var externalModule = false;
        function nextToken() {
            var token = ts.scanner.scan();
            if (token === 17 /* OpenBraceToken */) {
                braceNesting++;
            }
            else if (token === 18 /* CloseBraceToken */) {
                braceNesting--;
            }
            return token;
        }
        function processTripleSlashDirectives() {
            var commentRanges = ts.getLeadingCommentRanges(sourceText, 0);
            ts.forEach(commentRanges, function (commentRange) {
                var comment = sourceText.substring(commentRange.pos, commentRange.end);
                var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, commentRange);
                if (referencePathMatchResult) {
                    isNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
                    var fileReference = referencePathMatchResult.fileReference;
                    if (fileReference) {
                        var collection = referencePathMatchResult.isTypeReferenceDirective
                            ? typeReferenceDirectives
                            : referencedFiles;
                        collection.push(fileReference);
                    }
                }
            });
        }
        function getFileReference() {
            var fileName = ts.scanner.getTokenValue();
            var pos = ts.scanner.getTokenPos();
            return { fileName: fileName, pos: pos, end: pos + fileName.length };
        }
        function recordAmbientExternalModule() {
            if (!ambientExternalModules) {
                ambientExternalModules = [];
            }
            ambientExternalModules.push({ ref: getFileReference(), depth: braceNesting });
        }
        function recordModuleName() {
            importedFiles.push(getFileReference());
            markAsExternalModuleIfTopLevel();
        }
        function markAsExternalModuleIfTopLevel() {
            if (braceNesting === 0) {
                externalModule = true;
            }
        }
        /**
         * Returns true if at least one token was consumed from the stream
         */
        function tryConsumeDeclare() {
            var token = ts.scanner.getToken();
            if (token === 124 /* DeclareKeyword */) {
                // declare module "mod"
                token = nextToken();
                if (token === 128 /* ModuleKeyword */) {
                    token = nextToken();
                    if (token === 9 /* StringLiteral */) {
                        recordAmbientExternalModule();
                    }
                }
                return true;
            }
            return false;
        }
        /**
         * Returns true if at least one token was consumed from the stream
         */
        function tryConsumeImport() {
            var token = ts.scanner.getToken();
            if (token === 91 /* ImportKeyword */) {
                token = nextToken();
                if (token === 19 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 9 /* StringLiteral */) {
                        // import("mod");
                        recordModuleName();
                        return true;
                    }
                }
                else if (token === 9 /* StringLiteral */) {
                    // import "mod";
                    recordModuleName();
                    return true;
                }
                else {
                    if (token === 71 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 140 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 9 /* StringLiteral */) {
                                // import d from "mod";
                                recordModuleName();
                                return true;
                            }
                        }
                        else if (token === 58 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                        else if (token === 26 /* CommaToken */) {
                            // consume comma and keep going
                            token = nextToken();
                        }
                        else {
                            // unknown syntax
                            return true;
                        }
                    }
                    if (token === 17 /* OpenBraceToken */) {
                        token = nextToken();
                        // consume "{ a as B, c, d as D}" clauses
                        // make sure that it stops on EOF
                        while (token !== 18 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                            token = nextToken();
                        }
                        if (token === 18 /* CloseBraceToken */) {
                            token = nextToken();
                            if (token === 140 /* FromKeyword */) {
                                token = nextToken();
                                if (token === 9 /* StringLiteral */) {
                                    // import {a as A} from "mod";
                                    // import d, {a, b as B} from "mod"
                                    recordModuleName();
                                }
                            }
                        }
                    }
                    else if (token === 39 /* AsteriskToken */) {
                        token = nextToken();
                        if (token === 118 /* AsKeyword */) {
                            token = nextToken();
                            if (token === 71 /* Identifier */ || ts.isKeyword(token)) {
                                token = nextToken();
                                if (token === 140 /* FromKeyword */) {
                                    token = nextToken();
                                    if (token === 9 /* StringLiteral */) {
                                        // import * as NS from "mod"
                                        // import d, * as NS from "mod"
                                        recordModuleName();
                                    }
                                }
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeExport() {
            var token = ts.scanner.getToken();
            if (token === 84 /* ExportKeyword */) {
                markAsExternalModuleIfTopLevel();
                token = nextToken();
                if (token === 17 /* OpenBraceToken */) {
                    token = nextToken();
                    // consume "{ a as B, c, d as D}" clauses
                    // make sure it stops on EOF
                    while (token !== 18 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                        token = nextToken();
                    }
                    if (token === 18 /* CloseBraceToken */) {
                        token = nextToken();
                        if (token === 140 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 9 /* StringLiteral */) {
                                // export {a as A} from "mod";
                                // export {a, b as B} from "mod"
                                recordModuleName();
                            }
                        }
                    }
                }
                else if (token === 39 /* AsteriskToken */) {
                    token = nextToken();
                    if (token === 140 /* FromKeyword */) {
                        token = nextToken();
                        if (token === 9 /* StringLiteral */) {
                            // export * from "mod"
                            recordModuleName();
                        }
                    }
                }
                else if (token === 91 /* ImportKeyword */) {
                    token = nextToken();
                    if (token === 71 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 58 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeRequireCall(skipCurrentToken) {
            var token = skipCurrentToken ? nextToken() : ts.scanner.getToken();
            if (token === 132 /* RequireKeyword */) {
                token = nextToken();
                if (token === 19 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 9 /* StringLiteral */) {
                        //  require("mod");
                        recordModuleName();
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeDefine() {
            var token = ts.scanner.getToken();
            if (token === 71 /* Identifier */ && ts.scanner.getTokenValue() === "define") {
                token = nextToken();
                if (token !== 19 /* OpenParenToken */) {
                    return true;
                }
                token = nextToken();
                if (token === 9 /* StringLiteral */) {
                    // looks like define ("modname", ... - skip string literal and comma
                    token = nextToken();
                    if (token === 26 /* CommaToken */) {
                        token = nextToken();
                    }
                    else {
                        // unexpected token
                        return true;
                    }
                }
                // should be start of dependency list
                if (token !== 21 /* OpenBracketToken */) {
                    return true;
                }
                // skip open bracket
                token = nextToken();
                // scan until ']' or EOF
                while (token !== 22 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
                    // record string literals as module names
                    if (token === 9 /* StringLiteral */) {
                        recordModuleName();
                    }
                    token = nextToken();
                }
                return true;
            }
            return false;
        }
        function processImports() {
            ts.scanner.setText(sourceText);
            nextToken();
            // Look for:
            //    import "mod";
            //    import d from "mod"
            //    import {a as A } from "mod";
            //    import * as NS  from "mod"
            //    import d, {a, b as B} from "mod"
            //    import i = require("mod");
            //    import("mod");
            //    export * from "mod"
            //    export {a as b} from "mod"
            //    export import i = require("mod")
            //    (for JavaScript files) require("mod")
            while (true) {
                if (ts.scanner.getToken() === 1 /* EndOfFileToken */) {
                    break;
                }
                // check if at least one of alternative have moved scanner forward
                if (tryConsumeDeclare() ||
                    tryConsumeImport() ||
                    tryConsumeExport() ||
                    (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) {
                    continue;
                }
                else {
                    nextToken();
                }
            }
            ts.scanner.setText(undefined);
        }
        if (readImportFiles) {
            processImports();
        }
        processTripleSlashDirectives();
        if (externalModule) {
            // for external modules module all nested ambient modules are augmentations
            if (ambientExternalModules) {
                // move all detected ambient modules to imported files since they need to be resolved
                for (var _i = 0, ambientExternalModules_1 = ambientExternalModules; _i < ambientExternalModules_1.length; _i++) {
                    var decl = ambientExternalModules_1[_i];
                    importedFiles.push(decl.ref);
                }
            }
            return { referencedFiles: referencedFiles, typeReferenceDirectives: typeReferenceDirectives, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: undefined };
        }
        else {
            // for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0
            var ambientModuleNames = void 0;
            if (ambientExternalModules) {
                for (var _a = 0, ambientExternalModules_2 = ambientExternalModules; _a < ambientExternalModules_2.length; _a++) {
                    var decl = ambientExternalModules_2[_a];
                    if (decl.depth === 0) {
                        if (!ambientModuleNames) {
                            ambientModuleNames = [];
                        }
                        ambientModuleNames.push(decl.ref.fileName);
                    }
                    else {
                        importedFiles.push(decl.ref);
                    }
                }
            }
            return { referencedFiles: referencedFiles, typeReferenceDirectives: typeReferenceDirectives, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientModuleNames };
        }
    }
    ts.preProcessFile = preProcessFile;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Rename;
    (function (Rename) {
        function getRenameInfo(typeChecker, defaultLibFileName, getCanonicalFileName, sourceFile, position) {
            var getCanonicalDefaultLibName = ts.memoize(function () { return getCanonicalFileName(ts.normalizePath(defaultLibFileName)); });
            var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
            var renameInfo = node && nodeIsEligibleForRename(node)
                ? getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile)
                : undefined;
            return renameInfo || getRenameInfoError(ts.Diagnostics.You_cannot_rename_this_element);
            function isDefinedInLibraryFile(declaration) {
                if (!defaultLibFileName) {
                    return false;
                }
                var sourceFile = declaration.getSourceFile();
                var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
                return canonicalName === getCanonicalDefaultLibName();
            }
        }
        Rename.getRenameInfo = getRenameInfo;
        function getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile) {
            var symbol = typeChecker.getSymbolAtLocation(node);
            // Only allow a symbol to be renamed if it actually has at least one declaration.
            if (symbol) {
                var declarations = symbol.getDeclarations();
                if (declarations && declarations.length > 0) {
                    // Disallow rename for elements that are defined in the standard TypeScript library.
                    if (ts.some(declarations, isDefinedInLibraryFile)) {
                        return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
                    }
                    // Cannot rename `default` as in `import { default as foo } from "./someModule";
                    if (node.kind === 71 /* Identifier */ &&
                        node.originalKeywordKind === 79 /* DefaultKeyword */ &&
                        symbol.parent.flags & 1536 /* Module */) {
                        return undefined;
                    }
                    var displayName = ts.stripQuotes(ts.getDeclaredName(typeChecker, symbol, node));
                    var kind = ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
                    return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, ts.SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined;
                }
            }
            else if (node.kind === 9 /* StringLiteral */) {
                if (isDefinedInLibraryFile(node)) {
                    return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
                }
                var displayName = ts.stripQuotes(node.text);
                return getRenameInfoSuccess(displayName, displayName, "var" /* variableElement */, "" /* none */, node, sourceFile);
            }
        }
        function getRenameInfoSuccess(displayName, fullDisplayName, kind, kindModifiers, node, sourceFile) {
            return {
                canRename: true,
                kind: kind,
                displayName: displayName,
                localizedErrorMessage: undefined,
                fullDisplayName: fullDisplayName,
                kindModifiers: kindModifiers,
                triggerSpan: createTriggerSpanForNode(node, sourceFile)
            };
        }
        function getRenameInfoError(diagnostic) {
            return {
                canRename: false,
                localizedErrorMessage: ts.getLocaleSpecificMessage(diagnostic),
                displayName: undefined,
                fullDisplayName: undefined,
                kind: undefined,
                kindModifiers: undefined,
                triggerSpan: undefined
            };
        }
        function createTriggerSpanForNode(node, sourceFile) {
            var start = node.getStart(sourceFile);
            var width = node.getWidth(sourceFile);
            if (node.kind === 9 /* StringLiteral */) {
                // Exclude the quotes
                start += 1;
                width -= 2;
            }
            return ts.createTextSpan(start, width);
        }
        function nodeIsEligibleForRename(node) {
            switch (node.kind) {
                case 71 /* Identifier */:
                case 9 /* StringLiteral */:
                case 99 /* ThisKeyword */:
                    return true;
                case 8 /* NumericLiteral */:
                    return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node);
                default:
                    return false;
            }
        }
    })(Rename = ts.Rename || (ts.Rename = {}));
})(ts || (ts = {}));
///<reference path='services.ts' />
/* @internal */
var ts;
(function (ts) {
    var SignatureHelp;
    (function (SignatureHelp) {
        var ArgumentListKind;
        (function (ArgumentListKind) {
            ArgumentListKind[ArgumentListKind["TypeArguments"] = 0] = "TypeArguments";
            ArgumentListKind[ArgumentListKind["CallArguments"] = 1] = "CallArguments";
            ArgumentListKind[ArgumentListKind["TaggedTemplateArguments"] = 2] = "TaggedTemplateArguments";
            ArgumentListKind[ArgumentListKind["JSXAttributesArguments"] = 3] = "JSXAttributesArguments";
        })(ArgumentListKind = SignatureHelp.ArgumentListKind || (SignatureHelp.ArgumentListKind = {}));
        function getSignatureHelpItems(program, sourceFile, position, cancellationToken) {
            var typeChecker = program.getTypeChecker();
            // Decide whether to show signature help
            var startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position);
            if (!startingToken) {
                // We are at the beginning of the file
                return undefined;
            }
            var argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile);
            if (!argumentInfo)
                return undefined;
            cancellationToken.throwIfCancellationRequested();
            // Semantic filtering of signature help
            var call = argumentInfo.invocation;
            var candidates = [];
            var resolvedSignature = typeChecker.getResolvedSignature(call, candidates, argumentInfo.argumentCount);
            cancellationToken.throwIfCancellationRequested();
            if (!candidates.length) {
                // We didn't have any sig help items produced by the TS compiler.  If this is a JS
                // file, then see if we can figure out anything better.
                if (ts.isSourceFileJavaScript(sourceFile)) {
                    return createJavaScriptSignatureHelpItems(argumentInfo, program);
                }
                return undefined;
            }
            return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker);
        }
        SignatureHelp.getSignatureHelpItems = getSignatureHelpItems;
        function createJavaScriptSignatureHelpItems(argumentInfo, program) {
            if (argumentInfo.invocation.kind !== 181 /* CallExpression */) {
                return undefined;
            }
            // See if we can find some symbol with the call expression name that has call signatures.
            var callExpression = argumentInfo.invocation;
            var expression = callExpression.expression;
            var name = expression.kind === 71 /* Identifier */
                ? expression
                : expression.kind === 179 /* PropertyAccessExpression */
                    ? expression.name
                    : undefined;
            if (!name || !name.escapedText) {
                return undefined;
            }
            var typeChecker = program.getTypeChecker();
            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                var nameToDeclarations = sourceFile.getNamedDeclarations();
                var declarations = nameToDeclarations.get(name.text);
                if (declarations) {
                    for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) {
                        var declaration = declarations_12[_b];
                        var symbol = declaration.symbol;
                        if (symbol) {
                            var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration);
                            if (type) {
                                var callSignatures = type.getCallSignatures();
                                if (callSignatures && callSignatures.length) {
                                    return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker);
                                }
                            }
                        }
                    }
                }
            }
        }
        /**
         * Returns relevant information for the argument list and the current argument if we are
         * in the argument of an invocation; returns undefined otherwise.
         */
        function getImmediatelyContainingArgumentInfo(node, position, sourceFile) {
            if (ts.isCallOrNewExpression(node.parent)) {
                var invocation = node.parent;
                var list = void 0;
                var argumentIndex = void 0;
                // There are 3 cases to handle:
                //   1. The token introduces a list, and should begin a signature help session
                //   2. The token is either not associated with a list, or ends a list, so the session should end
                //   3. The token is buried inside a list, and should give signature help
                //
                // The following are examples of each:
                //
                //    Case 1:
                //          foo<#T, U>(#a, b)    -> The token introduces a list, and should begin a signature help session
                //    Case 2:
                //          fo#o<T, U>#(a, b)#   -> The token is either not associated with a list, or ends a list, so the session should end
                //    Case 3:
                //          foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
                // Find out if 'node' is an argument, a type argument, or neither
                if (node.kind === 27 /* LessThanToken */ || node.kind === 19 /* OpenParenToken */) {
                    // Find the list that starts right *after* the < or ( token.
                    // If the user has just opened a list, consider this item 0.
                    list = getChildListThatStartsWithOpenerToken(invocation, node, sourceFile);
                    ts.Debug.assert(list !== undefined);
                    argumentIndex = 0;
                }
                else {
                    // findListItemInfo can return undefined if we are not in parent's argument list
                    // or type argument list. This includes cases where the cursor is:
                    //   - To the right of the closing parenthesis, non-substitution template, or template tail.
                    //   - Between the type arguments and the arguments (greater than token)
                    //   - On the target of the call (parent.func)
                    //   - On the 'new' keyword in a 'new' expression
                    list = ts.findContainingList(node);
                    if (!list)
                        return undefined;
                    argumentIndex = getArgumentIndex(list, node);
                }
                var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 /* TypeArguments */ : 1 /* CallArguments */;
                var argumentCount = getArgumentCount(list);
                if (argumentIndex !== 0) {
                    ts.Debug.assertLessThan(argumentIndex, argumentCount);
                }
                var argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
                return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount };
            }
            else if (node.kind === 13 /* NoSubstitutionTemplateLiteral */ && node.parent.kind === 183 /* TaggedTemplateExpression */) {
                // Check if we're actually inside the template;
                // otherwise we'll fall out and return undefined.
                if (ts.isInsideTemplateLiteral(node, position)) {
                    return getArgumentListInfoForTemplate(node.parent, /*argumentIndex*/ 0, sourceFile);
                }
            }
            else if (node.kind === 14 /* TemplateHead */ && node.parent.parent.kind === 183 /* TaggedTemplateExpression */) {
                var templateExpression = node.parent;
                var tagExpression = templateExpression.parent;
                ts.Debug.assert(templateExpression.kind === 196 /* TemplateExpression */);
                var argumentIndex = ts.isInsideTemplateLiteral(node, position) ? 0 : 1;
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (node.parent.kind === 205 /* TemplateSpan */ && node.parent.parent.parent.kind === 183 /* TaggedTemplateExpression */) {
                var templateSpan = node.parent;
                var templateExpression = templateSpan.parent;
                var tagExpression = templateExpression.parent;
                ts.Debug.assert(templateExpression.kind === 196 /* TemplateExpression */);
                // If we're just after a template tail, don't show signature help.
                if (node.kind === 16 /* TemplateTail */ && !ts.isInsideTemplateLiteral(node, position)) {
                    return undefined;
                }
                var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
                var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position);
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (node.parent && ts.isJsxOpeningLikeElement(node.parent)) {
                // Provide a signature help for JSX opening element or JSX self-closing element.
                // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems")
                // i.e
                //      export function MainButton(props: ButtonProps, context: any): JSX.Element { ... }
                //      <MainButton /*signatureHelp*/
                var attributeSpanStart = node.parent.attributes.getFullStart();
                var attributeSpanEnd = ts.skipTrivia(sourceFile.text, node.parent.attributes.getEnd(), /*stopAfterLineBreak*/ false);
                return {
                    kind: 3 /* JSXAttributesArguments */,
                    invocation: node.parent,
                    argumentsSpan: ts.createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
                    argumentIndex: 0,
                    argumentCount: 1
                };
            }
            return undefined;
        }
        SignatureHelp.getImmediatelyContainingArgumentInfo = getImmediatelyContainingArgumentInfo;
        function getArgumentIndex(argumentsList, node) {
            // The list we got back can include commas.  In the presence of errors it may
            // also just have nodes without commas.  For example "Foo(a b c)" will have 3
            // args without commas.   We want to find what index we're at.  So we count
            // forward until we hit ourselves, only incrementing the index if it isn't a
            // comma.
            //
            // Note: the subtlety around trailing commas (in getArgumentCount) does not apply
            // here.  That's because we're only walking forward until we hit the node we're
            // on.  In that case, even if we're after the trailing comma, we'll still see
            // that trailing comma in the list, and we'll have generated the appropriate
            // arg index.
            var argumentIndex = 0;
            var listChildren = argumentsList.getChildren();
            for (var _i = 0, listChildren_1 = listChildren; _i < listChildren_1.length; _i++) {
                var child = listChildren_1[_i];
                if (child === node) {
                    break;
                }
                if (child.kind !== 26 /* CommaToken */) {
                    argumentIndex++;
                }
            }
            return argumentIndex;
        }
        function getArgumentCount(argumentsList) {
            // The argument count for a list is normally the number of non-comma children it has.
            // For example, if you have "Foo(a,b)" then there will be three children of the arg
            // list 'a' '<comma>' 'b'.  So, in this case the arg count will be 2.  However, there
            // is a small subtlety.  If you have  "Foo(a,)", then the child list will just have
            // 'a' '<comma>'.  So, in the case where the last child is a comma, we increase the
            // arg count by one to compensate.
            //
            // Note: this subtlety only applies to the last comma.  If you had "Foo(a,,"  then
            // we'll have:  'a' '<comma>' '<missing>'
            // That will give us 2 non-commas.  We then add one for the last comma, giving us an
            // arg count of 3.
            var listChildren = argumentsList.getChildren();
            var argumentCount = ts.countWhere(listChildren, function (arg) { return arg.kind !== 26 /* CommaToken */; });
            if (listChildren.length > 0 && ts.lastOrUndefined(listChildren).kind === 26 /* CommaToken */) {
                argumentCount++;
            }
            return argumentCount;
        }
        // spanIndex is either the index for a given template span.
        // This does not give appropriate results for a NoSubstitutionTemplateLiteral
        function getArgumentIndexForTemplatePiece(spanIndex, node, position) {
            // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1.
            // There are three cases we can encounter:
            //      1. We are precisely in the template literal (argIndex = 0).
            //      2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1).
            //      3. We are directly to the right of the template literal, but because we look for the token on the left,
            //          not enough to put us in the substitution expression; we should consider ourselves part of
            //          the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1).
            //
            // Example: f  `# abcd $#{#  1 + 1#  }# efghi ${ #"#hello"#  }  #  `
            //              ^       ^ ^       ^   ^          ^ ^      ^     ^
            // Case:        1       1 3       2   1          3 2      2     1
            ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node.");
            if (ts.isTemplateLiteralKind(node.kind)) {
                if (ts.isInsideTemplateLiteral(node, position)) {
                    return 0;
                }
                return spanIndex + 2;
            }
            return spanIndex + 1;
        }
        function getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile) {
            // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument.
            var argumentCount = tagExpression.template.kind === 13 /* NoSubstitutionTemplateLiteral */
                ? 1
                : tagExpression.template.templateSpans.length + 1;
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            return {
                kind: 2 /* TaggedTemplateArguments */,
                invocation: tagExpression,
                argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile),
                argumentIndex: argumentIndex,
                argumentCount: argumentCount
            };
        }
        function getApplicableSpanForArguments(argumentsList, sourceFile) {
            // We use full start and skip trivia on the end because we want to include trivia on
            // both sides. For example,
            //
            //    foo(   /*comment */     a, b, c      /*comment*/     )
            //        |                                               |
            //
            // The applicable span is from the first bar to the second bar (inclusive,
            // but not including parentheses)
            var applicableSpanStart = argumentsList.getFullStart();
            var applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false);
            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
        }
        function getApplicableSpanForTaggedTemplate(taggedTemplate, sourceFile) {
            var template = taggedTemplate.template;
            var applicableSpanStart = template.getStart();
            var applicableSpanEnd = template.getEnd();
            // We need to adjust the end position for the case where the template does not have a tail.
            // Otherwise, we will not show signature help past the expression.
            // For example,
            //
            //      `  ${ 1 + 1        foo(10)
            //       |        |
            //
            // This is because a Missing node has no width. However, what we actually want is to include trivia
            // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail.
            if (template.kind === 196 /* TemplateExpression */) {
                var lastSpan = ts.lastOrUndefined(template.templateSpans);
                if (lastSpan.literal.getFullWidth() === 0) {
                    applicableSpanEnd = ts.skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
                }
            }
            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
        }
        function getContainingArgumentInfo(node, position, sourceFile) {
            for (var n = node; n.kind !== 265 /* SourceFile */; n = n.parent) {
                if (ts.isFunctionBlock(n)) {
                    return undefined;
                }
                // If the node is not a subspan of its parent, this is a big problem.
                // There have been crashes that might be caused by this violation.
                if (n.pos < n.parent.pos || n.end > n.parent.end) {
                    ts.Debug.fail("Node of kind " + n.kind + " is not a subspan of its parent of kind " + n.parent.kind);
                }
                var argumentInfo = getImmediatelyContainingArgumentInfo(n, position, sourceFile);
                if (argumentInfo) {
                    return argumentInfo;
                }
                // TODO: Handle generic call with incomplete syntax
            }
            return undefined;
        }
        SignatureHelp.getContainingArgumentInfo = getContainingArgumentInfo;
        function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) {
            var children = parent.getChildren(sourceFile);
            var indexOfOpenerToken = children.indexOf(openerToken);
            ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
            return children[indexOfOpenerToken + 1];
        }
        function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) {
            var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex;
            var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */;
            var callTarget = ts.getInvokedExpression(invocation);
            var callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget);
            var callTargetDisplayParts = callTargetSymbol && ts.symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
            var items = ts.map(candidates, function (candidateSignature) {
                var signatureHelpParameters;
                var prefixDisplayParts = [];
                var suffixDisplayParts = [];
                if (callTargetDisplayParts) {
                    ts.addRange(prefixDisplayParts, callTargetDisplayParts);
                }
                var isVariadic;
                if (isTypeParameterList) {
                    isVariadic = false; // type parameter lists are not variadic
                    prefixDisplayParts.push(ts.punctuationPart(27 /* LessThanToken */));
                    var typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
                    signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray;
                    suffixDisplayParts.push(ts.punctuationPart(29 /* GreaterThanToken */));
                    var parameterParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation);
                    });
                    ts.addRange(suffixDisplayParts, parameterParts);
                }
                else {
                    isVariadic = candidateSignature.hasRestParameter;
                    var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation);
                    });
                    ts.addRange(prefixDisplayParts, typeParameterParts);
                    prefixDisplayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
                    signatureHelpParameters = ts.map(candidateSignature.parameters, createSignatureHelpParameterForParameter);
                    suffixDisplayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
                }
                var returnTypeParts = ts.mapToDisplayParts(function (writer) {
                    return typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation);
                });
                ts.addRange(suffixDisplayParts, returnTypeParts);
                return {
                    isVariadic: isVariadic,
                    prefixDisplayParts: prefixDisplayParts,
                    suffixDisplayParts: suffixDisplayParts,
                    separatorDisplayParts: [ts.punctuationPart(26 /* CommaToken */), ts.spacePart()],
                    parameters: signatureHelpParameters,
                    documentation: candidateSignature.getDocumentationComment(),
                    tags: candidateSignature.getJsDocTags()
                };
            });
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            var selectedItemIndex = candidates.indexOf(resolvedSignature);
            ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
            return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount };
            function createSignatureHelpParameterForParameter(parameter) {
                var displayParts = ts.mapToDisplayParts(function (writer) {
                    return typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation);
                });
                return {
                    name: parameter.name,
                    documentation: parameter.getDocumentationComment(),
                    displayParts: displayParts,
                    isOptional: typeChecker.isOptionalParameter(parameter.valueDeclaration)
                };
            }
            function createSignatureHelpParameterForTypeParameter(typeParameter) {
                var displayParts = ts.mapToDisplayParts(function (writer) {
                    return typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation);
                });
                return {
                    name: typeParameter.symbol.name,
                    documentation: ts.emptyArray,
                    displayParts: displayParts,
                    isOptional: false
                };
            }
        }
    })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SymbolDisplay;
    (function (SymbolDisplay) {
        // TODO(drosen): use contextual SemanticMeaning.
        function getSymbolKind(typeChecker, symbol, location) {
            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            if (flags & 32 /* Class */) {
                return ts.getDeclarationOfKind(symbol, 199 /* ClassExpression */) ?
                    "local class" /* localClassElement */ : "class" /* classElement */;
            }
            if (flags & 384 /* Enum */)
                return "enum" /* enumElement */;
            if (flags & 524288 /* TypeAlias */)
                return "type" /* typeElement */;
            if (flags & 64 /* Interface */)
                return "interface" /* interfaceElement */;
            if (flags & 262144 /* TypeParameter */)
                return "type parameter" /* typeParameterElement */;
            var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
            if (result === "" /* unknown */) {
                if (flags & 262144 /* TypeParameter */)
                    return "type parameter" /* typeParameterElement */;
                if (flags & 8 /* EnumMember */)
                    return "enum member" /* enumMemberElement */;
                if (flags & 2097152 /* Alias */)
                    return "alias" /* alias */;
                if (flags & 1536 /* Module */)
                    return "module" /* moduleElement */;
            }
            return result;
        }
        SymbolDisplay.getSymbolKind = getSymbolKind;
        function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) {
            if (typeChecker.isUndefinedSymbol(symbol)) {
                return "var" /* variableElement */;
            }
            if (typeChecker.isArgumentsSymbol(symbol)) {
                return "local var" /* localVariableElement */;
            }
            if (location.kind === 99 /* ThisKeyword */ && ts.isExpression(location)) {
                return "parameter" /* parameterElement */;
            }
            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            if (flags & 3 /* Variable */) {
                if (ts.isFirstDeclarationOfSymbolParameter(symbol)) {
                    return "parameter" /* parameterElement */;
                }
                else if (symbol.valueDeclaration && ts.isConst(symbol.valueDeclaration)) {
                    return "const" /* constElement */;
                }
                else if (ts.forEach(symbol.declarations, ts.isLet)) {
                    return "let" /* letElement */;
                }
                return isLocalVariableOrFunction(symbol) ? "local var" /* localVariableElement */ : "var" /* variableElement */;
            }
            if (flags & 16 /* Function */)
                return isLocalVariableOrFunction(symbol) ? "local function" /* localFunctionElement */ : "function" /* functionElement */;
            if (flags & 32768 /* GetAccessor */)
                return "getter" /* memberGetAccessorElement */;
            if (flags & 65536 /* SetAccessor */)
                return "setter" /* memberSetAccessorElement */;
            if (flags & 8192 /* Method */)
                return "method" /* memberFunctionElement */;
            if (flags & 16384 /* Constructor */)
                return "constructor" /* constructorImplementationElement */;
            if (flags & 4 /* Property */) {
                if (flags & 33554432 /* Transient */ && symbol.checkFlags & 6 /* Synthetic */) {
                    // If union property is result of union of non method (property/accessors/variables), it is labeled as property
                    var unionPropertyKind = ts.forEach(typeChecker.getRootSymbols(symbol), function (rootSymbol) {
                        var rootSymbolFlags = rootSymbol.getFlags();
                        if (rootSymbolFlags & (98308 /* PropertyOrAccessor */ | 3 /* Variable */)) {
                            return "property" /* memberVariableElement */;
                        }
                        // May be a Function if this was from `typeof N` with `namespace N { function f();. }`.
                        ts.Debug.assert(!!(rootSymbolFlags & (8192 /* Method */ | 16 /* Function */)));
                    });
                    if (!unionPropertyKind) {
                        // If this was union of all methods,
                        // make sure it has call signatures before we can label it as method
                        var typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location);
                        if (typeOfUnionProperty.getCallSignatures().length) {
                            return "method" /* memberFunctionElement */;
                        }
                        return "property" /* memberVariableElement */;
                    }
                    return unionPropertyKind;
                }
                if (location.parent && ts.isJsxAttribute(location.parent)) {
                    return "JSX attribute" /* jsxAttribute */;
                }
                return "property" /* memberVariableElement */;
            }
            return "" /* unknown */;
        }
        function getSymbolModifiers(symbol) {
            return symbol && symbol.declarations && symbol.declarations.length > 0
                ? ts.getNodeModifiers(symbol.declarations[0])
                : "" /* none */;
        }
        SymbolDisplay.getSymbolModifiers = getSymbolModifiers;
        // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
        function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, enclosingDeclaration, location, semanticMeaning) {
            if (semanticMeaning === void 0) { semanticMeaning = ts.getMeaningFromLocation(location); }
            var displayParts = [];
            var documentation;
            var tags;
            var symbolFlags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
            var hasAddedSymbolInfo;
            var isThisExpression = location.kind === 99 /* ThisKeyword */ && ts.isExpression(location);
            var type;
            // Class at constructor site need to be shown as constructor apart from property,method, vars
            if (symbolKind !== "" /* unknown */ || symbolFlags & 32 /* Class */ || symbolFlags & 2097152 /* Alias */) {
                // If it is accessor they are allowed only if location is at name of the accessor
                if (symbolKind === "getter" /* memberGetAccessorElement */ || symbolKind === "setter" /* memberSetAccessorElement */) {
                    symbolKind = "property" /* memberVariableElement */;
                }
                var signature = void 0;
                type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol.exportSymbol || symbol, location);
                if (location.parent && location.parent.kind === 179 /* PropertyAccessExpression */) {
                    var right = location.parent.name;
                    // Either the location is on the right of a property access, or on the left and the right is missing
                    if (right === location || (right && right.getFullWidth() === 0)) {
                        location = location.parent;
                    }
                }
                // try get the call/construct signature from the type if it matches
                var callExpressionLike = void 0;
                if (ts.isCallOrNewExpression(location)) {
                    callExpressionLike = location;
                }
                else if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location)) {
                    callExpressionLike = location.parent;
                }
                else if (location.parent && ts.isJsxOpeningLikeElement(location.parent) && ts.isFunctionLike(symbol.valueDeclaration)) {
                    callExpressionLike = location.parent;
                }
                if (callExpressionLike) {
                    var candidateSignatures = [];
                    signature = typeChecker.getResolvedSignature(callExpressionLike, candidateSignatures);
                    var useConstructSignatures = callExpressionLike.kind === 182 /* NewExpression */ || (ts.isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === 97 /* SuperKeyword */);
                    var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures();
                    if (!ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) {
                        // Get the first signature if there is one -- allSignatures may contain
                        // either the original signature or its target, so check for either
                        signature = allSignatures.length ? allSignatures[0] : undefined;
                    }
                    if (signature) {
                        if (useConstructSignatures && (symbolFlags & 32 /* Class */)) {
                            // Constructor
                            symbolKind = "constructor" /* constructorImplementationElement */;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else if (symbolFlags & 2097152 /* Alias */) {
                            symbolKind = "alias" /* alias */;
                            pushTypePart(symbolKind);
                            displayParts.push(ts.spacePart());
                            if (useConstructSignatures) {
                                displayParts.push(ts.keywordPart(94 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            addFullSymbolName(symbol);
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        switch (symbolKind) {
                            case "JSX attribute" /* jsxAttribute */:
                            case "property" /* memberVariableElement */:
                            case "var" /* variableElement */:
                            case "const" /* constElement */:
                            case "let" /* letElement */:
                            case "parameter" /* parameterElement */:
                            case "local var" /* localVariableElement */:
                                // If it is call or construct signature of lambda's write type name
                                displayParts.push(ts.punctuationPart(56 /* ColonToken */));
                                displayParts.push(ts.spacePart());
                                if (useConstructSignatures) {
                                    displayParts.push(ts.keywordPart(94 /* NewKeyword */));
                                    displayParts.push(ts.spacePart());
                                }
                                if (!(type.flags & 32768 /* Object */ && type.objectFlags & 16 /* Anonymous */) && type.symbol) {
                                    ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */));
                                }
                                addSignatureDisplayParts(signature, allSignatures, 16 /* WriteArrowStyleSignature */);
                                break;
                            default:
                                // Just signature
                                addSignatureDisplayParts(signature, allSignatures);
                        }
                        hasAddedSymbolInfo = true;
                    }
                }
                else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration
                    (location.kind === 123 /* ConstructorKeyword */ && location.parent.kind === 152 /* Constructor */)) {
                    // get the signature from the declaration and write it
                    var functionDeclaration_1 = location.parent;
                    // Use function declaration to write the signatures only if the symbol corresponding to this declaration
                    var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) {
                        return declaration === (location.kind === 123 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1);
                    });
                    if (locationIsSymbolDeclaration) {
                        var allSignatures = functionDeclaration_1.kind === 152 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
                        if (!typeChecker.isImplementationOfOverload(functionDeclaration_1)) {
                            signature = typeChecker.getSignatureFromDeclaration(functionDeclaration_1);
                        }
                        else {
                            signature = allSignatures[0];
                        }
                        if (functionDeclaration_1.kind === 152 /* Constructor */) {
                            // show (constructor) Type(...) signature
                            symbolKind = "constructor" /* constructorImplementationElement */;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else {
                            // (function/method) symbol(..signature)
                            addPrefixForAnyFunctionOrVar(functionDeclaration_1.kind === 155 /* CallSignature */ &&
                                !(type.symbol.flags & 2048 /* TypeLiteral */ || type.symbol.flags & 4096 /* ObjectLiteral */) ? type.symbol : symbol, symbolKind);
                        }
                        addSignatureDisplayParts(signature, allSignatures);
                        hasAddedSymbolInfo = true;
                    }
                }
            }
            if (symbolFlags & 32 /* Class */ && !hasAddedSymbolInfo && !isThisExpression) {
                if (ts.getDeclarationOfKind(symbol, 199 /* ClassExpression */)) {
                    // Special case for class expressions because we would like to indicate that
                    // the class name is local to the class body (similar to function expression)
                    //      (local class) class <className>
                    pushTypePart("local class" /* localClassElement */);
                }
                else {
                    // Class declaration has name which is not local.
                    displayParts.push(ts.keywordPart(75 /* ClassKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.keywordPart(109 /* InterfaceKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if (symbolFlags & 524288 /* TypeAlias */) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.keywordPart(138 /* TypeKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
                displayParts.push(ts.spacePart());
                displayParts.push(ts.operatorPart(58 /* EqualsToken */));
                displayParts.push(ts.spacePart());
                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, 1024 /* InTypeAlias */));
            }
            if (symbolFlags & 384 /* Enum */) {
                addNewLineIfDisplayPartsExist();
                if (ts.forEach(symbol.declarations, ts.isConstEnumDeclaration)) {
                    displayParts.push(ts.keywordPart(76 /* ConstKeyword */));
                    displayParts.push(ts.spacePart());
                }
                displayParts.push(ts.keywordPart(83 /* EnumKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if (symbolFlags & 1536 /* Module */) {
                addNewLineIfDisplayPartsExist();
                var declaration = ts.getDeclarationOfKind(symbol, 233 /* ModuleDeclaration */);
                var isNamespace = declaration && declaration.name && declaration.name.kind === 71 /* Identifier */;
                displayParts.push(ts.keywordPart(isNamespace ? 129 /* NamespaceKeyword */ : 128 /* ModuleKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
                displayParts.push(ts.textPart("type parameter"));
                displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                if (symbol.parent) {
                    // Class/Interface type parameter
                    addInPrefix();
                    addFullSymbolName(symbol.parent, enclosingDeclaration);
                    writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
                }
                else {
                    // Method/function type parameter
                    var decl = ts.getDeclarationOfKind(symbol, 145 /* TypeParameter */);
                    ts.Debug.assert(decl !== undefined);
                    var declaration = decl.parent;
                    if (declaration) {
                        if (ts.isFunctionLikeKind(declaration.kind)) {
                            addInPrefix();
                            var signature = typeChecker.getSignatureFromDeclaration(declaration);
                            if (declaration.kind === 156 /* ConstructSignature */) {
                                displayParts.push(ts.keywordPart(94 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            else if (declaration.kind !== 155 /* CallSignature */ && declaration.name) {
                                addFullSymbolName(declaration.symbol);
                            }
                            ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 64 /* WriteTypeArgumentsOfSignature */));
                        }
                        else if (declaration.kind === 231 /* TypeAliasDeclaration */) {
                            // Type alias type parameter
                            // For example
                            //      type list<T> = T[];  // Both T will go through same code path
                            addInPrefix();
                            displayParts.push(ts.keywordPart(138 /* TypeKeyword */));
                            displayParts.push(ts.spacePart());
                            addFullSymbolName(declaration.symbol);
                            writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
                        }
                    }
                }
            }
            if (symbolFlags & 8 /* EnumMember */) {
                symbolKind = "enum member" /* enumMemberElement */;
                addPrefixForAnyFunctionOrVar(symbol, "enum member");
                var declaration = symbol.declarations[0];
                if (declaration.kind === 264 /* EnumMember */) {
                    var constantValue = typeChecker.getConstantValue(declaration);
                    if (constantValue !== undefined) {
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.operatorPart(58 /* EqualsToken */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.displayPart(ts.getTextOfConstantValue(constantValue), typeof constantValue === "number" ? ts.SymbolDisplayPartKind.numericLiteral : ts.SymbolDisplayPartKind.stringLiteral));
                    }
                }
            }
            if (symbolFlags & 2097152 /* Alias */) {
                addNewLineIfDisplayPartsExist();
                switch (symbol.declarations[0].kind) {
                    case 236 /* NamespaceExportDeclaration */:
                        displayParts.push(ts.keywordPart(84 /* ExportKeyword */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.keywordPart(129 /* NamespaceKeyword */));
                        break;
                    case 243 /* ExportAssignment */:
                        displayParts.push(ts.keywordPart(84 /* ExportKeyword */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.keywordPart(symbol.declarations[0].isExportEquals ? 58 /* EqualsToken */ : 79 /* DefaultKeyword */));
                        break;
                    default:
                        displayParts.push(ts.keywordPart(91 /* ImportKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                ts.forEach(symbol.declarations, function (declaration) {
                    if (declaration.kind === 237 /* ImportEqualsDeclaration */) {
                        var importEqualsDeclaration = declaration;
                        if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.operatorPart(58 /* EqualsToken */));
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.keywordPart(132 /* RequireKeyword */));
                            displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
                            displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), ts.SymbolDisplayPartKind.stringLiteral));
                            displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
                        }
                        else {
                            var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
                            if (internalAliasSymbol) {
                                displayParts.push(ts.spacePart());
                                displayParts.push(ts.operatorPart(58 /* EqualsToken */));
                                displayParts.push(ts.spacePart());
                                addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
                            }
                        }
                        return true;
                    }
                });
            }
            if (!hasAddedSymbolInfo) {
                if (symbolKind !== "" /* unknown */) {
                    if (type) {
                        if (isThisExpression) {
                            addNewLineIfDisplayPartsExist();
                            displayParts.push(ts.keywordPart(99 /* ThisKeyword */));
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        // For properties, variables and local vars: show the type
                        if (symbolKind === "property" /* memberVariableElement */ ||
                            symbolKind === "JSX attribute" /* jsxAttribute */ ||
                            symbolFlags & 3 /* Variable */ ||
                            symbolKind === "local var" /* localVariableElement */ ||
                            isThisExpression) {
                            displayParts.push(ts.punctuationPart(56 /* ColonToken */));
                            displayParts.push(ts.spacePart());
                            // If the type is type parameter, format it specially
                            if (type.symbol && type.symbol.flags & 262144 /* TypeParameter */) {
                                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                                    typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration);
                                });
                                ts.addRange(displayParts, typeParameterParts);
                            }
                            else {
                                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration));
                            }
                        }
                        else if (symbolFlags & 16 /* Function */ ||
                            symbolFlags & 8192 /* Method */ ||
                            symbolFlags & 16384 /* Constructor */ ||
                            symbolFlags & 131072 /* Signature */ ||
                            symbolFlags & 98304 /* Accessor */ ||
                            symbolKind === "method" /* memberFunctionElement */) {
                            var allSignatures = type.getNonNullableType().getCallSignatures();
                            if (allSignatures.length) {
                                addSignatureDisplayParts(allSignatures[0], allSignatures);
                            }
                        }
                    }
                }
                else {
                    symbolKind = getSymbolKind(typeChecker, symbol, location);
                }
            }
            if (!documentation) {
                documentation = symbol.getDocumentationComment();
                tags = symbol.getJsDocTags();
                if (documentation.length === 0 && symbolFlags & 4 /* Property */) {
                    // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
                    // there documentation comments might be attached to the right hand side symbol of their declarations.
                    // The pattern of such special property access is that the parent symbol is the symbol of the file.
                    if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 265 /* SourceFile */; })) {
                        for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                            var declaration = _a[_i];
                            if (!declaration.parent || declaration.parent.kind !== 194 /* BinaryExpression */) {
                                continue;
                            }
                            var rhsSymbol = typeChecker.getSymbolAtLocation(declaration.parent.right);
                            if (!rhsSymbol) {
                                continue;
                            }
                            documentation = rhsSymbol.getDocumentationComment();
                            tags = rhsSymbol.getJsDocTags();
                            if (documentation.length > 0) {
                                break;
                            }
                        }
                    }
                }
            }
            return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags };
            function addNewLineIfDisplayPartsExist() {
                if (displayParts.length) {
                    displayParts.push(ts.lineBreakPart());
                }
            }
            function addInPrefix() {
                displayParts.push(ts.spacePart());
                displayParts.push(ts.keywordPart(92 /* InKeyword */));
                displayParts.push(ts.spacePart());
            }
            function addFullSymbolName(symbol, enclosingDeclaration) {
                var fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */);
                ts.addRange(displayParts, fullSymbolDisplayParts);
            }
            function addPrefixForAnyFunctionOrVar(symbol, symbolKind) {
                addNewLineIfDisplayPartsExist();
                if (symbolKind) {
                    pushTypePart(symbolKind);
                    displayParts.push(ts.spacePart());
                    addFullSymbolName(symbol);
                }
            }
            function pushTypePart(symbolKind) {
                switch (symbolKind) {
                    case "var" /* variableElement */:
                    case "function" /* functionElement */:
                    case "let" /* letElement */:
                    case "const" /* constElement */:
                    case "constructor" /* constructorImplementationElement */:
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        return;
                    default:
                        displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
                        return;
                }
            }
            function addSignatureDisplayParts(signature, allSignatures, flags) {
                ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 64 /* WriteTypeArgumentsOfSignature */));
                if (allSignatures.length > 1) {
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.punctuationPart(19 /* OpenParenToken */));
                    displayParts.push(ts.operatorPart(37 /* PlusToken */));
                    displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), ts.SymbolDisplayPartKind.numericLiteral));
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads"));
                    displayParts.push(ts.punctuationPart(20 /* CloseParenToken */));
                }
                documentation = signature.getDocumentationComment();
                tags = signature.getJsDocTags();
            }
            function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                    typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
                });
                ts.addRange(displayParts, typeParameterParts);
            }
        }
        SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind;
        function isLocalVariableOrFunction(symbol) {
            if (symbol.parent) {
                return false; // This is exported symbol
            }
            return ts.forEach(symbol.declarations, function (declaration) {
                // Function expressions are local
                if (declaration.kind === 186 /* FunctionExpression */) {
                    return true;
                }
                if (declaration.kind !== 226 /* VariableDeclaration */ && declaration.kind !== 228 /* FunctionDeclaration */) {
                    return false;
                }
                // If the parent is not sourceFile or module block it is local variable
                for (var parent = declaration.parent; !ts.isFunctionBlock(parent); parent = parent.parent) {
                    // Reached source file or module block
                    if (parent.kind === 265 /* SourceFile */ || parent.kind === 234 /* ModuleBlock */) {
                        return false;
                    }
                }
                // parent is in function block
                return true;
            });
        }
    })(SymbolDisplay = ts.SymbolDisplay || (ts.SymbolDisplay = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /*
     * This function will compile source text from 'input' argument using specified compiler options.
     * If not options are provided - it will use a set of default compiler options.
     * Extra compiler options that will unconditionally be used by this function are:
     * - isolatedModules = true
     * - allowNonTsExtensions = true
     * - noLib = true
     * - noResolve = true
     */
    function transpileModule(input, transpileOptions) {
        var diagnostics = [];
        var options = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : ts.getDefaultCompilerOptions();
        options.isolatedModules = true;
        // transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.
        options.suppressOutputPathCheck = true;
        // Filename can be non-ts file.
        options.allowNonTsExtensions = true;
        // We are not returning a sourceFile for lib file when asked by the program,
        // so pass --noLib to avoid reporting a file not found error.
        options.noLib = true;
        // Clear out other settings that would not be used in transpiling this module
        options.lib = undefined;
        options.types = undefined;
        options.noEmit = undefined;
        options.noEmitOnError = undefined;
        options.paths = undefined;
        options.rootDirs = undefined;
        options.declaration = undefined;
        options.declarationDir = undefined;
        options.out = undefined;
        options.outFile = undefined;
        // We are not doing a full typecheck, we are not resolving the whole context,
        // so pass --noResolve to avoid reporting missing file errors.
        options.noResolve = true;
        // if jsx is specified then treat file as .tsx
        var inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts");
        var sourceFile = ts.createSourceFile(inputFileName, input, options.target);
        if (transpileOptions.moduleName) {
            sourceFile.moduleName = transpileOptions.moduleName;
        }
        if (transpileOptions.renamedDependencies) {
            sourceFile.renamedDependencies = ts.createMapFromTemplate(transpileOptions.renamedDependencies);
        }
        var newLine = ts.getNewLineCharacter(options);
        // Output
        var outputText;
        var sourceMapText;
        // Create a compilerHost object to allow the compiler to read and write files
        var compilerHost = {
            getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; },
            writeFile: function (name, text) {
                if (ts.fileExtensionIs(name, ".map")) {
                    ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name);
                    sourceMapText = text;
                }
                else {
                    ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name);
                    outputText = text;
                }
            },
            getDefaultLibFileName: function () { return "lib.d.ts"; },
            useCaseSensitiveFileNames: function () { return false; },
            getCanonicalFileName: function (fileName) { return fileName; },
            getCurrentDirectory: function () { return ""; },
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return fileName === inputFileName; },
            readFile: function () { return ""; },
            directoryExists: function () { return true; },
            getDirectories: function () { return []; }
        };
        var program = ts.createProgram([inputFileName], options, compilerHost);
        if (transpileOptions.reportDiagnostics) {
            ts.addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
            ts.addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
        }
        // Emit
        program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers);
        ts.Debug.assert(outputText !== undefined, "Output generation failed");
        return { outputText: outputText, diagnostics: diagnostics, sourceMapText: sourceMapText };
    }
    ts.transpileModule = transpileModule;
    /*
     * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
     */
    function transpile(input, compilerOptions, fileName, diagnostics, moduleName) {
        var output = transpileModule(input, { compilerOptions: compilerOptions, fileName: fileName, reportDiagnostics: !!diagnostics, moduleName: moduleName });
        // addRange correctly handles cases when wither 'from' or 'to' argument is missing
        ts.addRange(diagnostics, output.diagnostics);
        return output.outputText;
    }
    ts.transpile = transpile;
    var commandLineOptionsStringToEnum;
    /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
    /*@internal*/
    function fixupCompilerOptions(options, diagnostics) {
        // Lazily create this value to fix module loading errors.
        commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || ts.filter(ts.optionDeclarations, function (o) {
            return typeof o.type === "object" && !ts.forEachEntry(o.type, function (v) { return typeof v !== "number"; });
        });
        options = ts.cloneCompilerOptions(options);
        var _loop_7 = function (opt) {
            if (!ts.hasProperty(options, opt.name)) {
                return "continue";
            }
            var value = options[opt.name];
            // Value should be a key of opt.type
            if (ts.isString(value)) {
                // If value is not a string, this will fail
                options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics);
            }
            else {
                if (!ts.forEachEntry(opt.type, function (v) { return v === value; })) {
                    // Supplied value isn't a valid enum value.
                    diagnostics.push(ts.createCompilerDiagnosticForInvalidCustomType(opt));
                }
            }
        };
        for (var _i = 0, commandLineOptionsStringToEnum_1 = commandLineOptionsStringToEnum; _i < commandLineOptionsStringToEnum_1.length; _i++) {
            var opt = commandLineOptionsStringToEnum_1[_i];
            _loop_7(opt);
        }
        return options;
    }
    ts.fixupCompilerOptions = fixupCompilerOptions;
})(ts || (ts = {}));
/// <reference path="formatting.ts"/>
/// <reference path="..\..\compiler\scanner.ts"/>
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var standardScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
        var jsxScanner = ts.createScanner(5 /* Latest */, /*skipTrivia*/ false, 1 /* JSX */);
        var ScanAction;
        (function (ScanAction) {
            ScanAction[ScanAction["Scan"] = 0] = "Scan";
            ScanAction[ScanAction["RescanGreaterThanToken"] = 1] = "RescanGreaterThanToken";
            ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken";
            ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken";
            ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier";
            ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText";
        })(ScanAction || (ScanAction = {}));
        function getFormattingScanner(text, languageVariant, startPos, endPos, cb) {
            var scanner = languageVariant === 1 /* JSX */ ? jsxScanner : standardScanner;
            scanner.setText(text);
            scanner.setTextPos(startPos);
            var wasNewLine = true;
            var leadingTrivia;
            var trailingTrivia;
            var savedPos;
            var lastScanAction;
            var lastTokenInfo;
            var res = cb({
                advance: advance,
                readTokenInfo: readTokenInfo,
                isOnToken: isOnToken,
                getCurrentLeadingTrivia: function () { return leadingTrivia; },
                lastTrailingTriviaWasNewLine: function () { return wasNewLine; },
                skipToEndOf: skipToEndOf,
            });
            lastTokenInfo = undefined;
            scanner.setText(undefined);
            return res;
            function advance() {
                lastTokenInfo = undefined;
                var isStarted = scanner.getStartPos() !== startPos;
                if (isStarted) {
                    wasNewLine = trailingTrivia && ts.lastOrUndefined(trailingTrivia).kind === 4 /* NewLineTrivia */;
                }
                else {
                    scanner.scan();
                }
                leadingTrivia = undefined;
                trailingTrivia = undefined;
                var pos = scanner.getStartPos();
                // Read leading trivia and token
                while (pos < endPos) {
                    var t = scanner.getToken();
                    if (!ts.isTrivia(t)) {
                        break;
                    }
                    // consume leading trivia
                    scanner.scan();
                    var item = {
                        pos: pos,
                        end: scanner.getStartPos(),
                        kind: t
                    };
                    pos = scanner.getStartPos();
                    leadingTrivia = ts.append(leadingTrivia, item);
                }
                savedPos = scanner.getStartPos();
            }
            function shouldRescanGreaterThanToken(node) {
                switch (node.kind) {
                    case 31 /* GreaterThanEqualsToken */:
                    case 66 /* GreaterThanGreaterThanEqualsToken */:
                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 47 /* GreaterThanGreaterThanGreaterThanToken */:
                    case 46 /* GreaterThanGreaterThanToken */:
                        return true;
                }
                return false;
            }
            function shouldRescanJsxIdentifier(node) {
                if (node.parent) {
                    switch (node.parent.kind) {
                        case 253 /* JsxAttribute */:
                        case 251 /* JsxOpeningElement */:
                        case 252 /* JsxClosingElement */:
                        case 250 /* JsxSelfClosingElement */:
                            // May parse an identifier like `module-layout`; that will be scanned as a keyword at first, but we should parse the whole thing to get an identifier.
                            return ts.isKeyword(node.kind) || node.kind === 71 /* Identifier */;
                    }
                }
                return false;
            }
            function shouldRescanJsxText(node) {
                return node.kind === 10 /* JsxText */;
            }
            function shouldRescanSlashToken(container) {
                return container.kind === 12 /* RegularExpressionLiteral */;
            }
            function shouldRescanTemplateToken(container) {
                return container.kind === 15 /* TemplateMiddle */ ||
                    container.kind === 16 /* TemplateTail */;
            }
            function startsWithSlashToken(t) {
                return t === 41 /* SlashToken */ || t === 63 /* SlashEqualsToken */;
            }
            function readTokenInfo(n) {
                ts.Debug.assert(isOnToken());
                // normally scanner returns the smallest available token
                // check the kind of context node to determine if scanner should have more greedy behavior and consume more text.
                var expectedScanAction = shouldRescanGreaterThanToken(n)
                    ? 1 /* RescanGreaterThanToken */
                    : shouldRescanSlashToken(n)
                        ? 2 /* RescanSlashToken */
                        : shouldRescanTemplateToken(n)
                            ? 3 /* RescanTemplateToken */
                            : shouldRescanJsxIdentifier(n)
                                ? 4 /* RescanJsxIdentifier */
                                : shouldRescanJsxText(n)
                                    ? 5 /* RescanJsxText */
                                    : 0 /* Scan */;
                if (lastTokenInfo && expectedScanAction === lastScanAction) {
                    // readTokenInfo was called before with the same expected scan action.
                    // No need to re-scan text, return existing 'lastTokenInfo'
                    // it is ok to call fixTokenKind here since it does not affect
                    // what portion of text is consumed. In contrast rescanning can change it,
                    // i.e. for '>=' when originally scanner eats just one character
                    // and rescanning forces it to consume more.
                    return fixTokenKind(lastTokenInfo, n);
                }
                if (scanner.getStartPos() !== savedPos) {
                    ts.Debug.assert(lastTokenInfo !== undefined);
                    // readTokenInfo was called before but scan action differs - rescan text
                    scanner.setTextPos(savedPos);
                    scanner.scan();
                }
                var currentToken = getNextToken(n, expectedScanAction);
                var token = {
                    pos: scanner.getStartPos(),
                    end: scanner.getTextPos(),
                    kind: currentToken
                };
                // consume trailing trivia
                if (trailingTrivia) {
                    trailingTrivia = undefined;
                }
                while (scanner.getStartPos() < endPos) {
                    currentToken = scanner.scan();
                    if (!ts.isTrivia(currentToken)) {
                        break;
                    }
                    var trivia = {
                        pos: scanner.getStartPos(),
                        end: scanner.getTextPos(),
                        kind: currentToken
                    };
                    if (!trailingTrivia) {
                        trailingTrivia = [];
                    }
                    trailingTrivia.push(trivia);
                    if (currentToken === 4 /* NewLineTrivia */) {
                        // move past new line
                        scanner.scan();
                        break;
                    }
                }
                lastTokenInfo = { leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, token: token };
                return fixTokenKind(lastTokenInfo, n);
            }
            function getNextToken(n, expectedScanAction) {
                var token = scanner.getToken();
                lastScanAction = 0 /* Scan */;
                switch (expectedScanAction) {
                    case 1 /* RescanGreaterThanToken */:
                        if (token === 29 /* GreaterThanToken */) {
                            lastScanAction = 1 /* RescanGreaterThanToken */;
                            var newToken = scanner.reScanGreaterToken();
                            ts.Debug.assert(n.kind === newToken);
                            return newToken;
                        }
                        break;
                    case 2 /* RescanSlashToken */:
                        if (startsWithSlashToken(token)) {
                            lastScanAction = 2 /* RescanSlashToken */;
                            var newToken = scanner.reScanSlashToken();
                            ts.Debug.assert(n.kind === newToken);
                            return newToken;
                        }
                        break;
                    case 3 /* RescanTemplateToken */:
                        if (token === 18 /* CloseBraceToken */) {
                            lastScanAction = 3 /* RescanTemplateToken */;
                            return scanner.reScanTemplateToken();
                        }
                        break;
                    case 4 /* RescanJsxIdentifier */:
                        lastScanAction = 4 /* RescanJsxIdentifier */;
                        return scanner.scanJsxIdentifier();
                    case 5 /* RescanJsxText */:
                        lastScanAction = 5 /* RescanJsxText */;
                        return scanner.reScanJsxToken();
                    case 0 /* Scan */:
                        break;
                    default:
                        ts.Debug.assertNever(expectedScanAction);
                }
                return token;
            }
            function isOnToken() {
                var current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
                var startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos();
                return startPos < endPos && current !== 1 /* EndOfFileToken */ && !ts.isTrivia(current);
            }
            // when containing node in the tree is token
            // but its kind differs from the kind that was returned by the scanner,
            // then kind needs to be fixed. This might happen in cases
            // when parser interprets token differently, i.e keyword treated as identifier
            function fixTokenKind(tokenInfo, container) {
                if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) {
                    tokenInfo.token.kind = container.kind;
                }
                return tokenInfo;
            }
            function skipToEndOf(node) {
                scanner.setTextPos(node.end);
                savedPos = scanner.getStartPos();
                lastScanAction = undefined;
                lastTokenInfo = undefined;
                wasNewLine = false;
                leadingTrivia = undefined;
                trailingTrivia = undefined;
            }
        }
        formatting.getFormattingScanner = getFormattingScanner;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/// <reference path="references.ts"/>
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var FormattingContext = /** @class */ (function () {
            function FormattingContext(sourceFile, formattingRequestKind, options) {
                this.sourceFile = sourceFile;
                this.formattingRequestKind = formattingRequestKind;
                this.options = options;
            }
            FormattingContext.prototype.updateContext = function (currentRange, currentTokenParent, nextRange, nextTokenParent, commonParent) {
                ts.Debug.assert(currentRange !== undefined, "currentTokenSpan is null");
                ts.Debug.assert(currentTokenParent !== undefined, "currentTokenParent is null");
                ts.Debug.assert(nextRange !== undefined, "nextTokenSpan is null");
                ts.Debug.assert(nextTokenParent !== undefined, "nextTokenParent is null");
                ts.Debug.assert(commonParent !== undefined, "commonParent is null");
                this.currentTokenSpan = currentRange;
                this.currentTokenParent = currentTokenParent;
                this.nextTokenSpan = nextRange;
                this.nextTokenParent = nextTokenParent;
                this.contextNode = commonParent;
                // drop cached results
                this.contextNodeAllOnSameLine = undefined;
                this.nextNodeAllOnSameLine = undefined;
                this.tokensAreOnSameLine = undefined;
                this.contextNodeBlockIsOnOneLine = undefined;
                this.nextNodeBlockIsOnOneLine = undefined;
            };
            FormattingContext.prototype.ContextNodeAllOnSameLine = function () {
                if (this.contextNodeAllOnSameLine === undefined) {
                    this.contextNodeAllOnSameLine = this.NodeIsOnOneLine(this.contextNode);
                }
                return this.contextNodeAllOnSameLine;
            };
            FormattingContext.prototype.NextNodeAllOnSameLine = function () {
                if (this.nextNodeAllOnSameLine === undefined) {
                    this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent);
                }
                return this.nextNodeAllOnSameLine;
            };
            FormattingContext.prototype.TokensAreOnSameLine = function () {
                if (this.tokensAreOnSameLine === undefined) {
                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line;
                    this.tokensAreOnSameLine = (startLine === endLine);
                }
                return this.tokensAreOnSameLine;
            };
            FormattingContext.prototype.ContextNodeBlockIsOnOneLine = function () {
                if (this.contextNodeBlockIsOnOneLine === undefined) {
                    this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode);
                }
                return this.contextNodeBlockIsOnOneLine;
            };
            FormattingContext.prototype.NextNodeBlockIsOnOneLine = function () {
                if (this.nextNodeBlockIsOnOneLine === undefined) {
                    this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent);
                }
                return this.nextNodeBlockIsOnOneLine;
            };
            FormattingContext.prototype.NodeIsOnOneLine = function (node) {
                var startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line;
                var endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
                return startLine === endLine;
            };
            FormattingContext.prototype.BlockIsOnOneLine = function (node) {
                var openBrace = ts.findChildOfKind(node, 17 /* OpenBraceToken */, this.sourceFile);
                var closeBrace = ts.findChildOfKind(node, 18 /* CloseBraceToken */, this.sourceFile);
                if (openBrace && closeBrace) {
                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(openBrace.getEnd()).line;
                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(closeBrace.getStart(this.sourceFile)).line;
                    return startLine === endLine;
                }
                return false;
            };
            return FormattingContext;
        }());
        formatting.FormattingContext = FormattingContext;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/// <reference path="references.ts"/>
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var FormattingRequestKind;
        (function (FormattingRequestKind) {
            FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument";
            FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection";
            FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter";
            FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon";
            FormattingRequestKind[FormattingRequestKind["FormatOnOpeningCurlyBrace"] = 4] = "FormatOnOpeningCurlyBrace";
            FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 5] = "FormatOnClosingCurlyBrace";
        })(FormattingRequestKind = formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var Rule = /** @class */ (function () {
            function Rule(Descriptor, Operation, Flag) {
                if (Flag === void 0) { Flag = 0 /* None */; }
                this.Descriptor = Descriptor;
                this.Operation = Operation;
                this.Flag = Flag;
            }
            return Rule;
        }());
        formatting.Rule = Rule;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RuleAction;
        (function (RuleAction) {
            RuleAction[RuleAction["Ignore"] = 1] = "Ignore";
            RuleAction[RuleAction["Space"] = 2] = "Space";
            RuleAction[RuleAction["NewLine"] = 4] = "NewLine";
            RuleAction[RuleAction["Delete"] = 8] = "Delete";
        })(RuleAction = formatting.RuleAction || (formatting.RuleAction = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RuleDescriptor = /** @class */ (function () {
            function RuleDescriptor(LeftTokenRange, RightTokenRange) {
                this.LeftTokenRange = LeftTokenRange;
                this.RightTokenRange = RightTokenRange;
            }
            RuleDescriptor.prototype.toString = function () {
                return "[leftRange=" + this.LeftTokenRange + "," +
                    "rightRange=" + this.RightTokenRange + "]";
            };
            RuleDescriptor.create1 = function (left, right) {
                return RuleDescriptor.create4(formatting.Shared.TokenRange.FromToken(left), formatting.Shared.TokenRange.FromToken(right));
            };
            RuleDescriptor.create2 = function (left, right) {
                return RuleDescriptor.create4(left, formatting.Shared.TokenRange.FromToken(right));
            };
            RuleDescriptor.create3 = function (left, right) {
                return RuleDescriptor.create4(formatting.Shared.TokenRange.FromToken(left), right);
            };
            RuleDescriptor.create4 = function (left, right) {
                return new RuleDescriptor(left, right);
            };
            return RuleDescriptor;
        }());
        formatting.RuleDescriptor = RuleDescriptor;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RuleFlags;
        (function (RuleFlags) {
            RuleFlags[RuleFlags["None"] = 0] = "None";
            RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines";
        })(RuleFlags = formatting.RuleFlags || (formatting.RuleFlags = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RuleOperation = /** @class */ (function () {
            function RuleOperation(Context, Action) {
                this.Context = Context;
                this.Action = Action;
            }
            RuleOperation.prototype.toString = function () {
                return "[context=" + this.Context + "," +
                    "action=" + this.Action + "]";
            };
            RuleOperation.create1 = function (action) {
                return RuleOperation.create2(formatting.RuleOperationContext.Any, action);
            };
            RuleOperation.create2 = function (context, action) {
                return new RuleOperation(context, action);
            };
            return RuleOperation;
        }());
        formatting.RuleOperation = RuleOperation;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RuleOperationContext = /** @class */ (function () {
            function RuleOperationContext() {
                var funcs = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    funcs[_i] = arguments[_i];
                }
                this.customContextChecks = funcs;
            }
            RuleOperationContext.prototype.IsAny = function () {
                return this === RuleOperationContext.Any;
            };
            RuleOperationContext.prototype.InContext = function (context) {
                if (this.IsAny()) {
                    return true;
                }
                for (var _i = 0, _a = this.customContextChecks; _i < _a.length; _i++) {
                    var check = _a[_i];
                    if (!check(context)) {
                        return false;
                    }
                }
                return true;
            };
            RuleOperationContext.Any = new RuleOperationContext();
            return RuleOperationContext;
        }());
        formatting.RuleOperationContext = RuleOperationContext;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var Rules = /** @class */ (function () {
            function Rules() {
                ///
                /// Common Rules
                ///
                // Leave comments alone
                this.IgnoreBeforeComment = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.Comments), formatting.RuleOperation.create1(1 /* Ignore */));
                this.IgnoreAfterLineComment = new formatting.Rule(formatting.RuleDescriptor.create3(2 /* SingleLineCommentTrivia */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create1(1 /* Ignore */));
                // Space after keyword but not before ; or : or ?
                this.NoSpaceBeforeSemicolon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 25 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeColon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 56 /* ColonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                this.NoSpaceBeforeQuestionMark = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 55 /* QuestionToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                this.SpaceAfterColon = new formatting.Rule(formatting.RuleDescriptor.create3(56 /* ColonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 2 /* Space */));
                this.SpaceAfterQuestionMarkInConditionalOperator = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* QuestionToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConditionalOperatorContext), 2 /* Space */));
                this.NoSpaceAfterQuestionMark = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* QuestionToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterSemicolon = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // Space after }.
                this.SpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* CloseBraceToken */, formatting.Shared.TokenRange.FromRange(0 /* FirstToken */, 142 /* LastToken */, [20 /* CloseParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsAfterCodeBlockContext), 2 /* Space */));
                // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
                this.SpaceBetweenCloseBraceAndElse = new formatting.Rule(formatting.RuleDescriptor.create1(18 /* CloseBraceToken */, 82 /* ElseKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBetweenCloseBraceAndWhile = new formatting.Rule(formatting.RuleDescriptor.create1(18 /* CloseBraceToken */, 106 /* WhileKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* CloseBraceToken */, formatting.Shared.TokenRange.FromTokens([22 /* CloseBracketToken */, 26 /* CommaToken */, 25 /* SemicolonToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // No space for dot
                this.NoSpaceBeforeDot = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 23 /* DotToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterDot = new formatting.Rule(formatting.RuleDescriptor.create3(23 /* DotToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // No space before and after indexer
                this.NoSpaceBeforeOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.AnyExcept(120 /* AsyncKeyword */), 21 /* OpenBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(22 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), 8 /* Delete */));
                // Place a space before open brace in a function declaration
                this.FunctionOpenBraceLeftTokenRange = formatting.Shared.TokenRange.AnyIncludingMultilineComments;
                this.SpaceBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
                this.TypeScriptOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([71 /* Identifier */, 3 /* MultiLineCommentTrivia */, 75 /* ClassKeyword */, 84 /* ExportKeyword */, 91 /* ImportKeyword */]);
                this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                // Place a space before open brace in a control flow construct
                this.ControlOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([20 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 81 /* DoKeyword */, 102 /* TryKeyword */, 87 /* FinallyKeyword */, 82 /* ElseKeyword */]);
                this.SpaceBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
                this.SpaceAfterOpenBrace = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), 2 /* Space */));
                this.SpaceBeforeCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), 2 /* Space */));
                this.NoSpaceAfterOpenBrace = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBetweenEmptyBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(17 /* OpenBraceToken */, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), 8 /* Delete */));
                // Insert new line after { and before } in multi-line contexts.
                this.NewLineAfterOpenBraceInBlockContext = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsMultilineBlockContext), 4 /* NewLine */));
                // For functions and control block place } on a new line    [multi-line rule]
                this.NewLineBeforeCloseBraceInBlockContext = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.AnyIncludingMultilineComments, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsMultilineBlockContext), 4 /* NewLine */));
                // Special handling of unary operators.
                // Prefix operators generally shouldn't have a space between
                // them and their target unary expression.
                this.NoSpaceAfterUnaryPrefixOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.UnaryPrefixOperators, formatting.Shared.TokenRange.UnaryPrefixExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                this.NoSpaceAfterUnaryPreincrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(43 /* PlusPlusToken */, formatting.Shared.TokenRange.UnaryPreincrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterUnaryPredecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(44 /* MinusMinusToken */, formatting.Shared.TokenRange.UnaryPredecrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeUnaryPostincrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostincrementExpressions, 43 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeUnaryPostdecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostdecrementExpressions, 44 /* MinusMinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // More unary operator special-casing.
                // DevDiv 181814:  Be careful when removing leading whitespace
                // around unary operators.  Examples:
                //      1 - -2  --X-->  1--2
                //      a + ++b --X-->  a+++b
                this.SpaceAfterPostincrementWhenFollowedByAdd = new formatting.Rule(formatting.RuleDescriptor.create1(43 /* PlusPlusToken */, 37 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterAddWhenFollowedByUnaryPlus = new formatting.Rule(formatting.RuleDescriptor.create1(37 /* PlusToken */, 37 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterAddWhenFollowedByPreincrement = new formatting.Rule(formatting.RuleDescriptor.create1(37 /* PlusToken */, 43 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterPostdecrementWhenFollowedBySubtract = new formatting.Rule(formatting.RuleDescriptor.create1(44 /* MinusMinusToken */, 38 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterSubtractWhenFollowedByUnaryMinus = new formatting.Rule(formatting.RuleDescriptor.create1(38 /* MinusToken */, 38 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterSubtractWhenFollowedByPredecrement = new formatting.Rule(formatting.RuleDescriptor.create1(38 /* MinusToken */, 44 /* MinusMinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.NoSpaceBeforeComma = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 26 /* CommaToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterCertainKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([104 /* VarKeyword */, 100 /* ThrowKeyword */, 94 /* NewKeyword */, 80 /* DeleteKeyword */, 96 /* ReturnKeyword */, 103 /* TypeOfKeyword */, 121 /* AwaitKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceAfterNewKeywordOnConstructorSignature = new formatting.Rule(formatting.RuleDescriptor.create1(94 /* NewKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConstructorSignatureContext), 8 /* Delete */));
                this.SpaceAfterLetConstInVariableDeclaration = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([110 /* LetKeyword */, 76 /* ConstKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), 2 /* Space */));
                this.NoSpaceBeforeOpenParenInFuncCall = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), 8 /* Delete */));
                this.SpaceAfterFunctionInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create3(89 /* FunctionKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                this.SpaceBeforeOpenParenInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), 2 /* Space */));
                this.NoSpaceBeforeOpenParenInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), 8 /* Delete */));
                this.SpaceAfterVoidOperator = new formatting.Rule(formatting.RuleDescriptor.create3(105 /* VoidKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), 2 /* Space */));
                this.NoSpaceBetweenReturnAndSemicolon = new formatting.Rule(formatting.RuleDescriptor.create1(96 /* ReturnKeyword */, 25 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
                // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
                this.SpaceBetweenStatements = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([20 /* CloseParenToken */, 81 /* DoKeyword */, 82 /* ElseKeyword */, 73 /* CaseKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), 2 /* Space */));
                // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
                this.SpaceAfterTryFinally = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([102 /* TryKeyword */, 87 /* FinallyKeyword */]), 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                //      get x() {}
                //      set x(val) {}
                this.SpaceAfterGetSetInMember = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([125 /* GetKeyword */, 135 /* SetKeyword */]), 71 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options.
                this.SpaceBeforeBinaryKeywordOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryKeywordOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterBinaryKeywordOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryKeywordOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                // TypeScript-specific higher priority rules
                this.SpaceAfterConstructor = new formatting.Rule(formatting.RuleDescriptor.create1(123 /* ConstructorKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceAfterConstructor = new formatting.Rule(formatting.RuleDescriptor.create1(123 /* ConstructorKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // Use of module as a function call. e.g.: import m2 = module("m2");
                this.NoSpaceAfterModuleImport = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([128 /* ModuleKeyword */, 132 /* RequireKeyword */]), 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // Add a space around certain TypeScript keywords
                this.SpaceAfterCertainTypeScriptKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([117 /* AbstractKeyword */, 75 /* ClassKeyword */, 124 /* DeclareKeyword */, 79 /* DefaultKeyword */, 83 /* EnumKeyword */, 84 /* ExportKeyword */, 85 /* ExtendsKeyword */, 125 /* GetKeyword */, 108 /* ImplementsKeyword */, 91 /* ImportKeyword */, 109 /* InterfaceKeyword */, 128 /* ModuleKeyword */, 129 /* NamespaceKeyword */, 112 /* PrivateKeyword */, 114 /* PublicKeyword */, 113 /* ProtectedKeyword */, 131 /* ReadonlyKeyword */, 135 /* SetKeyword */, 115 /* StaticKeyword */, 138 /* TypeKeyword */, 140 /* FromKeyword */, 127 /* KeyOfKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBeforeCertainTypeScriptKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([85 /* ExtendsKeyword */, 108 /* ImplementsKeyword */, 140 /* FromKeyword */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
                this.SpaceAfterModuleName = new formatting.Rule(formatting.RuleDescriptor.create1(9 /* StringLiteral */, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsModuleDeclContext), 2 /* Space */));
                // Lambda expressions
                this.SpaceBeforeArrow = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 36 /* EqualsGreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceAfterArrow = new formatting.Rule(formatting.RuleDescriptor.create3(36 /* EqualsGreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // Optional parameters and let args
                this.NoSpaceAfterEllipsis = new formatting.Rule(formatting.RuleDescriptor.create1(24 /* DotDotDotToken */, 71 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterOptionalParameters = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* QuestionToken */, formatting.Shared.TokenRange.FromTokens([20 /* CloseParenToken */, 26 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                // generics and type assertions
                this.NoSpaceBeforeOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.TypeNames, 27 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceBetweenCloseParenAndAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create1(20 /* CloseParenToken */, 27 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceAfterOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(27 /* LessThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceBeforeCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 29 /* GreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceAfterCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(29 /* GreaterThanToken */, formatting.Shared.TokenRange.FromTokens([19 /* OpenParenToken */, 21 /* OpenBracketToken */, 29 /* GreaterThanToken */, 26 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                // Remove spaces in empty interface literals. e.g.: x: {}
                this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(17 /* OpenBraceToken */, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectTypeContext), 8 /* Delete */));
                // decorators
                this.SpaceBeforeAt = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 57 /* AtToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceAfterAt = new formatting.Rule(formatting.RuleDescriptor.create3(57 /* AtToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterDecorator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([117 /* AbstractKeyword */, 71 /* Identifier */, 84 /* ExportKeyword */, 79 /* DefaultKeyword */, 75 /* ClassKeyword */, 115 /* StaticKeyword */, 114 /* PublicKeyword */, 112 /* PrivateKeyword */, 113 /* ProtectedKeyword */, 125 /* GetKeyword */, 135 /* SetKeyword */, 21 /* OpenBracketToken */, 39 /* AsteriskToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), 2 /* Space */));
                this.NoSpaceBetweenFunctionKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(89 /* FunctionKeyword */, 39 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 8 /* Delete */));
                this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(39 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([71 /* Identifier */, 19 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */));
                this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(116 /* YieldKeyword */, 39 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8 /* Delete */));
                this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([116 /* YieldKeyword */, 39 /* AsteriskToken */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2 /* Space */));
                // Async-await
                this.SpaceBetweenAsyncAndOpenParen = new formatting.Rule(formatting.RuleDescriptor.create1(120 /* AsyncKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsArrowFunctionContext, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(120 /* AsyncKeyword */, 89 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // template string
                this.NoSpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(71 /* Identifier */, formatting.Shared.TokenRange.FromTokens([13 /* NoSubstitutionTemplateLiteral */, 14 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // jsx opening element
                this.SpaceBeforeJsxAttribute = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 71 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBeforeSlashInJsxOpeningElement = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 41 /* SlashToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new formatting.Rule(formatting.RuleDescriptor.create1(41 /* SlashToken */, 29 /* GreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeEqualInJsxAttribute = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 58 /* EqualsToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterEqualInJsxAttribute = new formatting.Rule(formatting.RuleDescriptor.create3(58 /* EqualsToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // No space before non-null assertion operator
                this.NoSpaceBeforeNonNullAssertionOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 51 /* ExclamationToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonNullAssertionContext), 8 /* Delete */));
                ///
                /// Rules controlled by user options
                ///
                // Insert space after comma delimiter
                this.SpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(26 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), 2 /* Space */));
                this.NoSpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(26 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), 8 /* Delete */));
                // Insert space before and after binary operators
                this.SpaceBeforeBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.NoSpaceBeforeBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 8 /* Delete */));
                this.NoSpaceAfterBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 8 /* Delete */));
                // Insert space after keywords in control flow statements
                this.SpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), 2 /* Space */));
                this.NoSpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), 8 /* Delete */));
                // Open Brace braces after function
                // TypeScript: Function can have return types, which can be made of tons of different token kinds
                this.NewLineBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                // Open Brace braces after TypeScript module/class/interface
                this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                // Open Brace braces after control block
                this.NewLineBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 17 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                // Insert space after semicolon in for statement
                this.SpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 2 /* Space */));
                this.NoSpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 8 /* Delete */));
                // Insert space after opening and before closing nonempty parenthesis
                this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBetweenOpenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // Insert space after opening and before closing nonempty brackets
                this.SpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 22 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBetweenBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(21 /* OpenBracketToken */, 22 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 22 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // Insert space after opening and before closing template string braces
                this.NoSpaceAfterTemplateHeadAndMiddle = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([14 /* TemplateHead */, 15 /* TemplateMiddle */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterTemplateHeadAndMiddle = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([14 /* TemplateHead */, 15 /* TemplateMiddle */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBeforeTemplateMiddleAndTail = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([15 /* TemplateMiddle */, 16 /* TemplateTail */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceBeforeTemplateMiddleAndTail = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([15 /* TemplateMiddle */, 16 /* TemplateTail */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // No space after { and before } in JSX expression
                this.NoSpaceAfterOpenBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 8 /* Delete */));
                this.SpaceAfterOpenBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 2 /* Space */));
                this.NoSpaceBeforeCloseBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 8 /* Delete */));
                this.SpaceBeforeCloseBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), 2 /* Space */));
                // Insert space after function keyword for anonymous functions
                this.SpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(89 /* FunctionKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), 2 /* Space */));
                this.NoSpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(89 /* FunctionKeyword */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), 8 /* Delete */));
                // No space after type assertion
                this.NoSpaceAfterTypeAssertion = new formatting.Rule(formatting.RuleDescriptor.create3(29 /* GreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), 8 /* Delete */));
                this.SpaceAfterTypeAssertion = new formatting.Rule(formatting.RuleDescriptor.create3(29 /* GreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), 2 /* Space */));
                // These rules are higher in priority than user-configurable rules.
                this.HighPriorityCommonRules = [
                    this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
                    this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQuestionMark, this.SpaceAfterQuestionMarkInConditionalOperator,
                    this.NoSpaceAfterQuestionMark,
                    this.NoSpaceBeforeDot, this.NoSpaceAfterDot,
                    this.NoSpaceAfterUnaryPrefixOperator,
                    this.NoSpaceAfterUnaryPreincrementOperator, this.NoSpaceAfterUnaryPredecrementOperator,
                    this.NoSpaceBeforeUnaryPostincrementOperator, this.NoSpaceBeforeUnaryPostdecrementOperator,
                    this.SpaceAfterPostincrementWhenFollowedByAdd,
                    this.SpaceAfterAddWhenFollowedByUnaryPlus, this.SpaceAfterAddWhenFollowedByPreincrement,
                    this.SpaceAfterPostdecrementWhenFollowedBySubtract,
                    this.SpaceAfterSubtractWhenFollowedByUnaryMinus, this.SpaceAfterSubtractWhenFollowedByPredecrement,
                    this.NoSpaceAfterCloseBrace,
                    this.NewLineBeforeCloseBraceInBlockContext,
                    this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets,
                    this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration,
                    this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember,
                    this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand,
                    this.NoSpaceBetweenReturnAndSemicolon,
                    this.SpaceAfterCertainKeywords,
                    this.SpaceAfterLetConstInVariableDeclaration,
                    this.NoSpaceBeforeOpenParenInFuncCall,
                    this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator,
                    this.SpaceAfterVoidOperator,
                    this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword,
                    this.NoSpaceBetweenTagAndTemplateString,
                    this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement,
                    this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
                    // TypeScript-specific rules
                    this.NoSpaceAfterModuleImport,
                    this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords,
                    this.SpaceAfterModuleName,
                    this.SpaceBeforeArrow, this.SpaceAfterArrow,
                    this.NoSpaceAfterEllipsis,
                    this.NoSpaceAfterOptionalParameters,
                    this.NoSpaceBetweenEmptyInterfaceBraceBrackets,
                    this.NoSpaceBeforeOpenAngularBracket,
                    this.NoSpaceBetweenCloseParenAndAngularBracket,
                    this.NoSpaceAfterOpenAngularBracket,
                    this.NoSpaceBeforeCloseAngularBracket,
                    this.NoSpaceAfterCloseAngularBracket,
                    this.SpaceBeforeAt,
                    this.NoSpaceAfterAt,
                    this.SpaceAfterDecorator,
                    this.NoSpaceBeforeNonNullAssertionOperator,
                    this.NoSpaceAfterNewKeywordOnConstructorSignature
                ];
                // These rules are applied after high priority rules.
                this.UserConfigurableRules = [
                    this.SpaceAfterConstructor, this.NoSpaceAfterConstructor,
                    this.SpaceAfterComma, this.NoSpaceAfterComma,
                    this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword,
                    this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl,
                    this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen,
                    this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket,
                    this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace,
                    this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail,
                    this.SpaceAfterOpenBraceInJsxExpression, this.SpaceBeforeCloseBraceInJsxExpression, this.NoSpaceAfterOpenBraceInJsxExpression, this.NoSpaceBeforeCloseBraceInJsxExpression,
                    this.SpaceAfterSemicolonInFor, this.NoSpaceAfterSemicolonInFor,
                    this.SpaceBeforeBinaryOperator, this.SpaceAfterBinaryOperator, this.NoSpaceBeforeBinaryOperator, this.NoSpaceAfterBinaryOperator,
                    this.SpaceBeforeOpenParenInFuncDecl, this.NoSpaceBeforeOpenParenInFuncDecl,
                    this.NewLineBeforeOpenBraceInControl,
                    this.NewLineBeforeOpenBraceInFunction, this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock,
                    this.SpaceAfterTypeAssertion, this.NoSpaceAfterTypeAssertion
                ];
                // These rules are lower in priority than user-configurable rules.
                this.LowPriorityCommonRules = [
                    this.NoSpaceBeforeSemicolon,
                    this.SpaceBeforeOpenBraceInControl, this.SpaceBeforeOpenBraceInFunction, this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock,
                    this.NoSpaceBeforeComma,
                    this.NoSpaceBeforeOpenBracket,
                    this.NoSpaceAfterCloseBracket,
                    this.SpaceAfterSemicolon,
                    this.SpaceBetweenStatements, this.SpaceAfterTryFinally
                ];
                if (ts.Debug.isDebugging) {
                    var o = this;
                    for (var name in o) {
                        var rule = o[name];
                        if (rule instanceof formatting.Rule) {
                            rule.debugName = name;
                        }
                    }
                }
            }
            ///
            /// Contexts
            ///
            Rules.IsOptionEnabled = function (optionName) {
                return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; };
            };
            Rules.IsOptionDisabled = function (optionName) {
                return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; };
            };
            Rules.IsOptionDisabledOrUndefined = function (optionName) {
                return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; };
            };
            Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine = function (optionName) {
                return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); };
            };
            Rules.IsOptionEnabledOrUndefined = function (optionName) {
                return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; };
            };
            Rules.IsForContext = function (context) {
                return context.contextNode.kind === 214 /* ForStatement */;
            };
            Rules.IsNotForContext = function (context) {
                return !Rules.IsForContext(context);
            };
            Rules.IsBinaryOpContext = function (context) {
                switch (context.contextNode.kind) {
                    case 194 /* BinaryExpression */:
                    case 195 /* ConditionalExpression */:
                    case 202 /* AsExpression */:
                    case 246 /* ExportSpecifier */:
                    case 242 /* ImportSpecifier */:
                    case 158 /* TypePredicate */:
                    case 166 /* UnionType */:
                    case 167 /* IntersectionType */:
                        return true;
                    // equals in binding elements: function foo([[x, y] = [1, 2]])
                    case 176 /* BindingElement */:
                    // equals in type X = ...
                    case 231 /* TypeAliasDeclaration */:
                    // equal in import a = module('a');
                    case 237 /* ImportEqualsDeclaration */:
                    // equal in let a = 0;
                    case 226 /* VariableDeclaration */:
                    // equal in p = 0;
                    case 146 /* Parameter */:
                    case 264 /* EnumMember */:
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                        return context.currentTokenSpan.kind === 58 /* EqualsToken */ || context.nextTokenSpan.kind === 58 /* EqualsToken */;
                    // "in" keyword in for (let x in []) { }
                    case 215 /* ForInStatement */:
                    // "in" keyword in [P in keyof T]: T[P]
                    case 145 /* TypeParameter */:
                        return context.currentTokenSpan.kind === 92 /* InKeyword */ || context.nextTokenSpan.kind === 92 /* InKeyword */;
                    // Technically, "of" is not a binary operator, but format it the same way as "in"
                    case 216 /* ForOfStatement */:
                        return context.currentTokenSpan.kind === 142 /* OfKeyword */ || context.nextTokenSpan.kind === 142 /* OfKeyword */;
                }
                return false;
            };
            Rules.IsNotBinaryOpContext = function (context) {
                return !Rules.IsBinaryOpContext(context);
            };
            Rules.IsConditionalOperatorContext = function (context) {
                return context.contextNode.kind === 195 /* ConditionalExpression */;
            };
            Rules.IsSameLineTokenOrBeforeBlockContext = function (context) {
                return context.TokensAreOnSameLine() || Rules.IsBeforeBlockContext(context);
            };
            Rules.IsBraceWrappedContext = function (context) {
                return context.contextNode.kind === 174 /* ObjectBindingPattern */ || Rules.IsSingleLineBlockContext(context);
            };
            // This check is done before an open brace in a control construct, a function, or a typescript block declaration
            Rules.IsBeforeMultilineBlockContext = function (context) {
                return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
            };
            Rules.IsMultilineBlockContext = function (context) {
                return Rules.IsBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
            };
            Rules.IsSingleLineBlockContext = function (context) {
                return Rules.IsBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
            };
            Rules.IsBlockContext = function (context) {
                return Rules.NodeIsBlockContext(context.contextNode);
            };
            Rules.IsBeforeBlockContext = function (context) {
                return Rules.NodeIsBlockContext(context.nextTokenParent);
            };
            // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children
            Rules.NodeIsBlockContext = function (node) {
                if (Rules.NodeIsTypeScriptDeclWithBlockContext(node)) {
                    // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc).
                    return true;
                }
                switch (node.kind) {
                    case 207 /* Block */:
                    case 235 /* CaseBlock */:
                    case 178 /* ObjectLiteralExpression */:
                    case 234 /* ModuleBlock */:
                        return true;
                }
                return false;
            };
            Rules.IsFunctionDeclContext = function (context) {
                switch (context.contextNode.kind) {
                    case 228 /* FunctionDeclaration */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                    // case SyntaxKind.MemberFunctionDeclaration:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    // case SyntaxKind.MethodSignature:
                    case 155 /* CallSignature */:
                    case 186 /* FunctionExpression */:
                    case 152 /* Constructor */:
                    case 187 /* ArrowFunction */:
                    // case SyntaxKind.ConstructorDeclaration:
                    // case SyntaxKind.SimpleArrowFunctionExpression:
                    // case SyntaxKind.ParenthesizedArrowFunctionExpression:
                    case 230 /* InterfaceDeclaration */:// This one is not truly a function, but for formatting purposes, it acts just like one
                        return true;
                }
                return false;
            };
            Rules.IsFunctionDeclarationOrFunctionExpressionContext = function (context) {
                return context.contextNode.kind === 228 /* FunctionDeclaration */ || context.contextNode.kind === 186 /* FunctionExpression */;
            };
            Rules.IsTypeScriptDeclWithBlockContext = function (context) {
                return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode);
            };
            Rules.NodeIsTypeScriptDeclWithBlockContext = function (node) {
                switch (node.kind) {
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 230 /* InterfaceDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 163 /* TypeLiteral */:
                    case 233 /* ModuleDeclaration */:
                    case 244 /* ExportDeclaration */:
                    case 245 /* NamedExports */:
                    case 238 /* ImportDeclaration */:
                    case 241 /* NamedImports */:
                        return true;
                }
                return false;
            };
            Rules.IsAfterCodeBlockContext = function (context) {
                switch (context.currentTokenParent.kind) {
                    case 229 /* ClassDeclaration */:
                    case 233 /* ModuleDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 260 /* CatchClause */:
                    case 234 /* ModuleBlock */:
                    case 221 /* SwitchStatement */:
                        return true;
                    case 207 /* Block */: {
                        var blockParent = context.currentTokenParent.parent;
                        // In a codefix scenario, we can't rely on parents being set. So just always return true.
                        if (!blockParent || blockParent.kind !== 187 /* ArrowFunction */ && blockParent.kind !== 186 /* FunctionExpression */) {
                            return true;
                        }
                    }
                }
                return false;
            };
            Rules.IsControlDeclContext = function (context) {
                switch (context.contextNode.kind) {
                    case 211 /* IfStatement */:
                    case 221 /* SwitchStatement */:
                    case 214 /* ForStatement */:
                    case 215 /* ForInStatement */:
                    case 216 /* ForOfStatement */:
                    case 213 /* WhileStatement */:
                    case 224 /* TryStatement */:
                    case 212 /* DoStatement */:
                    case 220 /* WithStatement */:
                    // TODO
                    // case SyntaxKind.ElseClause:
                    case 260 /* CatchClause */:
                        return true;
                    default:
                        return false;
                }
            };
            Rules.IsObjectContext = function (context) {
                return context.contextNode.kind === 178 /* ObjectLiteralExpression */;
            };
            Rules.IsFunctionCallContext = function (context) {
                return context.contextNode.kind === 181 /* CallExpression */;
            };
            Rules.IsNewContext = function (context) {
                return context.contextNode.kind === 182 /* NewExpression */;
            };
            Rules.IsFunctionCallOrNewContext = function (context) {
                return Rules.IsFunctionCallContext(context) || Rules.IsNewContext(context);
            };
            Rules.IsPreviousTokenNotComma = function (context) {
                return context.currentTokenSpan.kind !== 26 /* CommaToken */;
            };
            Rules.IsNextTokenNotCloseBracket = function (context) {
                return context.nextTokenSpan.kind !== 22 /* CloseBracketToken */;
            };
            Rules.IsArrowFunctionContext = function (context) {
                return context.contextNode.kind === 187 /* ArrowFunction */;
            };
            Rules.IsNonJsxSameLineTokenContext = function (context) {
                return context.TokensAreOnSameLine() && context.contextNode.kind !== 10 /* JsxText */;
            };
            Rules.IsNonJsxElementContext = function (context) {
                return context.contextNode.kind !== 249 /* JsxElement */;
            };
            Rules.IsJsxExpressionContext = function (context) {
                return context.contextNode.kind === 256 /* JsxExpression */;
            };
            Rules.IsNextTokenParentJsxAttribute = function (context) {
                return context.nextTokenParent.kind === 253 /* JsxAttribute */;
            };
            Rules.IsJsxAttributeContext = function (context) {
                return context.contextNode.kind === 253 /* JsxAttribute */;
            };
            Rules.IsJsxSelfClosingElementContext = function (context) {
                return context.contextNode.kind === 250 /* JsxSelfClosingElement */;
            };
            Rules.IsNotBeforeBlockInFunctionDeclarationContext = function (context) {
                return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context);
            };
            Rules.IsEndOfDecoratorContextOnSameLine = function (context) {
                return context.TokensAreOnSameLine() &&
                    context.contextNode.decorators &&
                    Rules.NodeIsInDecoratorContext(context.currentTokenParent) &&
                    !Rules.NodeIsInDecoratorContext(context.nextTokenParent);
            };
            Rules.NodeIsInDecoratorContext = function (node) {
                while (ts.isPartOfExpression(node)) {
                    node = node.parent;
                }
                return node.kind === 147 /* Decorator */;
            };
            Rules.IsStartOfVariableDeclarationList = function (context) {
                return context.currentTokenParent.kind === 227 /* VariableDeclarationList */ &&
                    context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos;
            };
            Rules.IsNotFormatOnEnter = function (context) {
                return context.formattingRequestKind !== 2 /* FormatOnEnter */;
            };
            Rules.IsModuleDeclContext = function (context) {
                return context.contextNode.kind === 233 /* ModuleDeclaration */;
            };
            Rules.IsObjectTypeContext = function (context) {
                return context.contextNode.kind === 163 /* TypeLiteral */; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
            };
            Rules.IsConstructorSignatureContext = function (context) {
                return context.contextNode.kind === 156 /* ConstructSignature */;
            };
            Rules.IsTypeArgumentOrParameterOrAssertion = function (token, parent) {
                if (token.kind !== 27 /* LessThanToken */ && token.kind !== 29 /* GreaterThanToken */) {
                    return false;
                }
                switch (parent.kind) {
                    case 159 /* TypeReference */:
                    case 184 /* TypeAssertionExpression */:
                    case 231 /* TypeAliasDeclaration */:
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 230 /* InterfaceDeclaration */:
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                    case 187 /* ArrowFunction */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                    case 155 /* CallSignature */:
                    case 156 /* ConstructSignature */:
                    case 181 /* CallExpression */:
                    case 182 /* NewExpression */:
                    case 201 /* ExpressionWithTypeArguments */:
                        return true;
                    default:
                        return false;
                }
            };
            Rules.IsTypeArgumentOrParameterOrAssertionContext = function (context) {
                return Rules.IsTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
                    Rules.IsTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
            };
            Rules.IsTypeAssertionContext = function (context) {
                return context.contextNode.kind === 184 /* TypeAssertionExpression */;
            };
            Rules.IsVoidOpContext = function (context) {
                return context.currentTokenSpan.kind === 105 /* VoidKeyword */ && context.currentTokenParent.kind === 190 /* VoidExpression */;
            };
            Rules.IsYieldOrYieldStarWithOperand = function (context) {
                return context.contextNode.kind === 197 /* YieldExpression */ && context.contextNode.expression !== undefined;
            };
            Rules.IsNonNullAssertionContext = function (context) {
                return context.contextNode.kind === 203 /* NonNullExpression */;
            };
            return Rules;
        }());
        formatting.Rules = Rules;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RulesMap = /** @class */ (function () {
            function RulesMap(rules) {
                this.mapRowLength = 142 /* LastToken */ + 1;
                this.map = new Array(this.mapRowLength * this.mapRowLength);
                // This array is used only during construction of the rulesbucket in the map
                var rulesBucketConstructionStateList = new Array(this.map.length);
                for (var _i = 0, rules_1 = rules; _i < rules_1.length; _i++) {
                    var rule = rules_1[_i];
                    this.FillRule(rule, rulesBucketConstructionStateList);
                }
            }
            RulesMap.prototype.GetRuleBucketIndex = function (row, column) {
                ts.Debug.assert(row <= 142 /* LastKeyword */ && column <= 142 /* LastKeyword */, "Must compute formatting context from tokens");
                return (row * this.mapRowLength) + column;
            };
            RulesMap.prototype.FillRule = function (rule, rulesBucketConstructionStateList) {
                var _this = this;
                var specificRule = rule.Descriptor.LeftTokenRange.isSpecific() && rule.Descriptor.RightTokenRange.isSpecific();
                rule.Descriptor.LeftTokenRange.GetTokens().forEach(function (left) {
                    rule.Descriptor.RightTokenRange.GetTokens().forEach(function (right) {
                        var rulesBucketIndex = _this.GetRuleBucketIndex(left, right);
                        var rulesBucket = _this.map[rulesBucketIndex];
                        if (rulesBucket === undefined) {
                            rulesBucket = _this.map[rulesBucketIndex] = new RulesBucket();
                        }
                        rulesBucket.AddRule(rule, specificRule, rulesBucketConstructionStateList, rulesBucketIndex);
                    });
                });
            };
            RulesMap.prototype.GetRule = function (context) {
                var bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
                var bucket = this.map[bucketIndex];
                if (bucket) {
                    for (var _i = 0, _a = bucket.Rules(); _i < _a.length; _i++) {
                        var rule = _a[_i];
                        if (rule.Operation.Context.InContext(context)) {
                            return rule;
                        }
                    }
                }
                return undefined;
            };
            return RulesMap;
        }());
        formatting.RulesMap = RulesMap;
        var MaskBitSize = 5;
        var Mask = 0x1f;
        var RulesPosition;
        (function (RulesPosition) {
            RulesPosition[RulesPosition["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific";
            RulesPosition[RulesPosition["IgnoreRulesAny"] = MaskBitSize * 1] = "IgnoreRulesAny";
            RulesPosition[RulesPosition["ContextRulesSpecific"] = MaskBitSize * 2] = "ContextRulesSpecific";
            RulesPosition[RulesPosition["ContextRulesAny"] = MaskBitSize * 3] = "ContextRulesAny";
            RulesPosition[RulesPosition["NoContextRulesSpecific"] = MaskBitSize * 4] = "NoContextRulesSpecific";
            RulesPosition[RulesPosition["NoContextRulesAny"] = MaskBitSize * 5] = "NoContextRulesAny";
        })(RulesPosition || (RulesPosition = {}));
        var RulesBucketConstructionState = /** @class */ (function () {
            function RulesBucketConstructionState() {
                //// The Rules list contains all the inserted rules into a rulebucket in the following order:
                ////    1- Ignore rules with specific token combination
                ////    2- Ignore rules with any token combination
                ////    3- Context rules with specific token combination
                ////    4- Context rules with any token combination
                ////    5- Non-context rules with specific token combination
                ////    6- Non-context rules with any token combination
                ////
                //// The member rulesInsertionIndexBitmap is used to describe the number of rules
                //// in each sub-bucket (above) hence can be used to know the index of where to insert
                //// the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
                ////
                //// Example:
                //// In order to insert a rule to the end of sub-bucket (3), we get the index by adding
                //// the values in the bitmap segments 3rd, 2nd, and 1st.
                this.rulesInsertionIndexBitmap = 0;
            }
            RulesBucketConstructionState.prototype.GetInsertionIndex = function (maskPosition) {
                var index = 0;
                var pos = 0;
                var indexBitmap = this.rulesInsertionIndexBitmap;
                while (pos <= maskPosition) {
                    index += (indexBitmap & Mask);
                    indexBitmap >>= MaskBitSize;
                    pos += MaskBitSize;
                }
                return index;
            };
            RulesBucketConstructionState.prototype.IncreaseInsertionIndex = function (maskPosition) {
                var value = (this.rulesInsertionIndexBitmap >> maskPosition) & Mask;
                value++;
                ts.Debug.assert((value & Mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
                var temp = this.rulesInsertionIndexBitmap & ~(Mask << maskPosition);
                temp |= value << maskPosition;
                this.rulesInsertionIndexBitmap = temp;
            };
            return RulesBucketConstructionState;
        }());
        formatting.RulesBucketConstructionState = RulesBucketConstructionState;
        var RulesBucket = /** @class */ (function () {
            function RulesBucket() {
                this.rules = [];
            }
            RulesBucket.prototype.Rules = function () {
                return this.rules;
            };
            RulesBucket.prototype.AddRule = function (rule, specificTokens, constructionState, rulesBucketIndex) {
                var position;
                if (rule.Operation.Action === 1 /* Ignore */) {
                    position = specificTokens ?
                        RulesPosition.IgnoreRulesSpecific :
                        RulesPosition.IgnoreRulesAny;
                }
                else if (!rule.Operation.Context.IsAny()) {
                    position = specificTokens ?
                        RulesPosition.ContextRulesSpecific :
                        RulesPosition.ContextRulesAny;
                }
                else {
                    position = specificTokens ?
                        RulesPosition.NoContextRulesSpecific :
                        RulesPosition.NoContextRulesAny;
                }
                var state = constructionState[rulesBucketIndex];
                if (state === undefined) {
                    state = constructionState[rulesBucketIndex] = new RulesBucketConstructionState();
                }
                var index = state.GetInsertionIndex(position);
                this.rules.splice(index, 0, rule);
                state.IncreaseInsertionIndex(position);
            };
            return RulesBucket;
        }());
        formatting.RulesBucket = RulesBucket;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var Shared;
        (function (Shared) {
            var allTokens = [];
            for (var token = 0 /* FirstToken */; token <= 142 /* LastToken */; token++) {
                allTokens.push(token);
            }
            var TokenValuesAccess = /** @class */ (function () {
                function TokenValuesAccess(tokens) {
                    if (tokens === void 0) { tokens = []; }
                    this.tokens = tokens;
                }
                TokenValuesAccess.prototype.GetTokens = function () {
                    return this.tokens;
                };
                TokenValuesAccess.prototype.Contains = function (token) {
                    return this.tokens.indexOf(token) >= 0;
                };
                TokenValuesAccess.prototype.isSpecific = function () { return true; };
                return TokenValuesAccess;
            }());
            var TokenSingleValueAccess = /** @class */ (function () {
                function TokenSingleValueAccess(token) {
                    this.token = token;
                }
                TokenSingleValueAccess.prototype.GetTokens = function () {
                    return [this.token];
                };
                TokenSingleValueAccess.prototype.Contains = function (tokenValue) {
                    return tokenValue === this.token;
                };
                TokenSingleValueAccess.prototype.isSpecific = function () { return true; };
                return TokenSingleValueAccess;
            }());
            var TokenAllAccess = /** @class */ (function () {
                function TokenAllAccess() {
                }
                TokenAllAccess.prototype.GetTokens = function () {
                    return allTokens;
                };
                TokenAllAccess.prototype.Contains = function () {
                    return true;
                };
                TokenAllAccess.prototype.toString = function () {
                    return "[allTokens]";
                };
                TokenAllAccess.prototype.isSpecific = function () { return false; };
                return TokenAllAccess;
            }());
            var TokenAllExceptAccess = /** @class */ (function () {
                function TokenAllExceptAccess(except) {
                    this.except = except;
                }
                TokenAllExceptAccess.prototype.GetTokens = function () {
                    var _this = this;
                    return allTokens.filter(function (t) { return t !== _this.except; });
                };
                TokenAllExceptAccess.prototype.Contains = function (token) {
                    return token !== this.except;
                };
                TokenAllExceptAccess.prototype.isSpecific = function () { return false; };
                return TokenAllExceptAccess;
            }());
            var TokenRange;
            (function (TokenRange) {
                function FromToken(token) {
                    return new TokenSingleValueAccess(token);
                }
                TokenRange.FromToken = FromToken;
                function FromTokens(tokens) {
                    return new TokenValuesAccess(tokens);
                }
                TokenRange.FromTokens = FromTokens;
                function FromRange(from, to, except) {
                    if (except === void 0) { except = []; }
                    var tokens = [];
                    for (var token = from; token <= to; token++) {
                        if (ts.indexOf(except, token) < 0) {
                            tokens.push(token);
                        }
                    }
                    return new TokenValuesAccess(tokens);
                }
                TokenRange.FromRange = FromRange;
                function AnyExcept(token) {
                    return new TokenAllExceptAccess(token);
                }
                TokenRange.AnyExcept = AnyExcept;
                TokenRange.Any = new TokenAllAccess();
                TokenRange.AnyIncludingMultilineComments = TokenRange.FromTokens(allTokens.concat([3 /* MultiLineCommentTrivia */]));
                TokenRange.Keywords = TokenRange.FromRange(72 /* FirstKeyword */, 142 /* LastKeyword */);
                TokenRange.BinaryOperators = TokenRange.FromRange(27 /* FirstBinaryOperator */, 70 /* LastBinaryOperator */);
                TokenRange.BinaryKeywordOperators = TokenRange.FromTokens([
                    92 /* InKeyword */, 93 /* InstanceOfKeyword */, 142 /* OfKeyword */, 118 /* AsKeyword */, 126 /* IsKeyword */
                ]);
                TokenRange.UnaryPrefixOperators = TokenRange.FromTokens([
                    43 /* PlusPlusToken */, 44 /* MinusMinusToken */, 52 /* TildeToken */, 51 /* ExclamationToken */
                ]);
                TokenRange.UnaryPrefixExpressions = TokenRange.FromTokens([
                    8 /* NumericLiteral */, 71 /* Identifier */, 19 /* OpenParenToken */, 21 /* OpenBracketToken */,
                    17 /* OpenBraceToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */
                ]);
                TokenRange.UnaryPreincrementExpressions = TokenRange.FromTokens([
                    71 /* Identifier */, 19 /* OpenParenToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */
                ]);
                TokenRange.UnaryPostincrementExpressions = TokenRange.FromTokens([
                    71 /* Identifier */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 94 /* NewKeyword */
                ]);
                TokenRange.UnaryPredecrementExpressions = TokenRange.FromTokens([
                    71 /* Identifier */, 19 /* OpenParenToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */
                ]);
                TokenRange.UnaryPostdecrementExpressions = TokenRange.FromTokens([
                    71 /* Identifier */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 94 /* NewKeyword */
                ]);
                TokenRange.Comments = TokenRange.FromTokens([2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */]);
                TokenRange.TypeNames = TokenRange.FromTokens([
                    71 /* Identifier */, 133 /* NumberKeyword */, 136 /* StringKeyword */, 122 /* BooleanKeyword */,
                    137 /* SymbolKeyword */, 105 /* VoidKeyword */, 119 /* AnyKeyword */
                ]);
            })(TokenRange = Shared.TokenRange || (Shared.TokenRange = {}));
        })(Shared = formatting.Shared || (formatting.Shared = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='..\services.ts' />
///<reference path='formattingContext.ts' />
///<reference path='formattingRequestKind.ts' />
///<reference path='rule.ts' />
///<reference path='ruleAction.ts' />
///<reference path='ruleDescriptor.ts' />
///<reference path='ruleFlag.ts' />
///<reference path='ruleOperation.ts' />
///<reference path='ruleOperationContext.ts' />
///<reference path='rules.ts' />
///<reference path='rulesMap.ts' />
///<reference path='tokenRange.ts' /> 
/// <reference path="references.ts"/>
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var RulesProvider = /** @class */ (function () {
            function RulesProvider() {
                this.globalRules = new formatting.Rules();
                var activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
                this.rulesMap = new formatting.RulesMap(activeRules);
            }
            RulesProvider.prototype.getRulesMap = function () {
                return this.rulesMap;
            };
            RulesProvider.prototype.getFormatOptions = function () {
                return this.options;
            };
            RulesProvider.prototype.ensureUpToDate = function (options) {
                if (!this.options || !ts.compareDataObjects(this.options, options)) {
                    this.options = ts.clone(options);
                }
            };
            return RulesProvider;
        }());
        formatting.RulesProvider = RulesProvider;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='..\services.ts' />
///<reference path='formattingScanner.ts' />
///<reference path='rulesProvider.ts' />
///<reference path='references.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var Constants;
        (function (Constants) {
            Constants[Constants["Unknown"] = -1] = "Unknown";
        })(Constants || (Constants = {}));
        function formatOnEnter(position, sourceFile, rulesProvider, options) {
            var line = sourceFile.getLineAndCharacterOfPosition(position).line;
            if (line === 0) {
                return [];
            }
            // After the enter key, the cursor is now at a new line. The new line may or may not contain non-whitespace characters.
            // If the new line has only whitespaces, we won't want to format this line, because that would remove the indentation as
            // trailing whitespaces. So the end of the formatting span should be the later one between:
            //  1. the end of the previous line
            //  2. the last non-whitespace character in the current line
            var endOfFormatSpan = ts.getEndLinePosition(line, sourceFile);
            while (ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(endOfFormatSpan))) {
                endOfFormatSpan--;
            }
            // if the character at the end of the span is a line break, we shouldn't include it, because it indicates we don't want to
            // touch the current line at all. Also, on some OSes the line break consists of two characters (\r\n), we should test if the
            // previous character before the end of format span is line break character as well.
            if (ts.isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) {
                endOfFormatSpan--;
            }
            var span = {
                // get start position for the previous line
                pos: ts.getStartPositionOfLine(line - 1, sourceFile),
                // end value is exclusive so add 1 to the result
                end: endOfFormatSpan + 1
            };
            return formatSpan(span, sourceFile, options, rulesProvider, 2 /* FormatOnEnter */);
        }
        formatting.formatOnEnter = formatOnEnter;
        function formatOnSemicolon(position, sourceFile, rulesProvider, options) {
            var semicolon = findImmediatelyPrecedingTokenOfKind(position, 25 /* SemicolonToken */, sourceFile);
            return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, options, rulesProvider, 3 /* FormatOnSemicolon */);
        }
        formatting.formatOnSemicolon = formatOnSemicolon;
        function formatOnOpeningCurly(position, sourceFile, rulesProvider, options) {
            var openingCurly = findImmediatelyPrecedingTokenOfKind(position, 17 /* OpenBraceToken */, sourceFile);
            if (!openingCurly) {
                return [];
            }
            var curlyBraceRange = openingCurly.parent;
            var outermostNode = findOutermostNodeWithinListLevel(curlyBraceRange);
            /**
             * We limit the span to end at the opening curly to handle the case where
             * the brace matched to that just typed will be incorrect after further edits.
             * For example, we could type the opening curly for the following method
             * body without brace-matching activated:
             * ```
             * class C {
             *     foo()
             * }
             * ```
             * and we wouldn't want to move the closing brace.
             */
            var textRange = {
                pos: ts.getLineStartPositionForPosition(outermostNode.getStart(sourceFile), sourceFile),
                end: position
            };
            return formatSpan(textRange, sourceFile, options, rulesProvider, 4 /* FormatOnOpeningCurlyBrace */);
        }
        formatting.formatOnOpeningCurly = formatOnOpeningCurly;
        function formatOnClosingCurly(position, sourceFile, rulesProvider, options) {
            var precedingToken = findImmediatelyPrecedingTokenOfKind(position, 18 /* CloseBraceToken */, sourceFile);
            return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, options, rulesProvider, 5 /* FormatOnClosingCurlyBrace */);
        }
        formatting.formatOnClosingCurly = formatOnClosingCurly;
        function formatDocument(sourceFile, rulesProvider, options) {
            var span = {
                pos: 0,
                end: sourceFile.text.length
            };
            return formatSpan(span, sourceFile, options, rulesProvider, 0 /* FormatDocument */);
        }
        formatting.formatDocument = formatDocument;
        function formatSelection(start, end, sourceFile, rulesProvider, options) {
            // format from the beginning of the line
            var span = {
                pos: ts.getLineStartPositionForPosition(start, sourceFile),
                end: end,
            };
            return formatSpan(span, sourceFile, options, rulesProvider, 1 /* FormatSelection */);
        }
        formatting.formatSelection = formatSelection;
        /**
         * Validating `expectedTokenKind` ensures the token was typed in the context we expect (eg: not a comment).
         * @param expectedTokenKind The kind of the last token constituting the desired parent node.
         */
        function findImmediatelyPrecedingTokenOfKind(end, expectedTokenKind, sourceFile) {
            var precedingToken = ts.findPrecedingToken(end, sourceFile);
            return precedingToken && precedingToken.kind === expectedTokenKind && end === precedingToken.getEnd() ?
                precedingToken :
                undefined;
        }
        /**
         * Finds the highest node enclosing `node` at the same list level as `node`
         * and whose end does not exceed `node.end`.
         *
         * Consider typing the following
         * ```
         * let x = 1;
         * while (true) {
         * }
         * ```
         * Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding
         * variable declaration.
         */
        function findOutermostNodeWithinListLevel(node) {
            var current = node;
            while (current &&
                current.parent &&
                current.parent.end === node.end &&
                !isListElement(current.parent, current)) {
                current = current.parent;
            }
            return current;
        }
        // Returns true if node is a element in some list in parent
        // i.e. parent is class declaration with the list of members and node is one of members.
        function isListElement(parent, node) {
            switch (parent.kind) {
                case 229 /* ClassDeclaration */:
                case 230 /* InterfaceDeclaration */:
                    return ts.rangeContainsRange(parent.members, node);
                case 233 /* ModuleDeclaration */:
                    var body = parent.body;
                    return body && body.kind === 234 /* ModuleBlock */ && ts.rangeContainsRange(body.statements, node);
                case 265 /* SourceFile */:
                case 207 /* Block */:
                case 234 /* ModuleBlock */:
                    return ts.rangeContainsRange(parent.statements, node);
                case 260 /* CatchClause */:
                    return ts.rangeContainsRange(parent.block.statements, node);
            }
            return false;
        }
        /** find node that fully contains given text range */
        function findEnclosingNode(range, sourceFile) {
            return find(sourceFile);
            function find(n) {
                var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; });
                if (candidate) {
                    var result = find(candidate);
                    if (result) {
                        return result;
                    }
                }
                return n;
            }
        }
        /** formatting is not applied to ranges that contain parse errors.
         * This function will return a predicate that for a given text range will tell
         * if there are any parse errors that overlap with the range.
         */
        function prepareRangeContainsErrorFunction(errors, originalRange) {
            if (!errors.length) {
                return rangeHasNoErrors;
            }
            // pick only errors that fall in range
            var sorted = errors
                .filter(function (d) { return ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); })
                .sort(function (e1, e2) { return e1.start - e2.start; });
            if (!sorted.length) {
                return rangeHasNoErrors;
            }
            var index = 0;
            return function (r) {
                // in current implementation sequence of arguments [r1, r2...] is monotonically increasing.
                // 'index' tracks the index of the most recent error that was checked.
                while (true) {
                    if (index >= sorted.length) {
                        // all errors in the range were already checked -> no error in specified range
                        return false;
                    }
                    var error = sorted[index];
                    if (r.end <= error.start) {
                        // specified range ends before the error refered by 'index' - no error in range
                        return false;
                    }
                    if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) {
                        // specified range overlaps with error range
                        return true;
                    }
                    index++;
                }
            };
            function rangeHasNoErrors() {
                return false;
            }
        }
        /**
         * Start of the original range might fall inside the comment - scanner will not yield appropriate results
         * This function will look for token that is located before the start of target range
         * and return its end as start position for the scanner.
         */
        function getScanStartPosition(enclosingNode, originalRange, sourceFile) {
            var start = enclosingNode.getStart(sourceFile);
            if (start === originalRange.pos && enclosingNode.end === originalRange.end) {
                return start;
            }
            var precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile);
            if (!precedingToken) {
                // no preceding token found - start from the beginning of enclosing node
                return enclosingNode.pos;
            }
            // preceding token ends after the start of original range (i.e when originalRange.pos falls in the middle of literal)
            // start from the beginning of enclosingNode to handle the entire 'originalRange'
            if (precedingToken.end >= originalRange.pos) {
                return enclosingNode.pos;
            }
            return precedingToken.end;
        }
        /*
         * For cases like
         * if (a ||
         *     b ||$
         *     c) {...}
         * If we hit Enter at $ we want line '    b ||' to be indented.
         * Formatting will be applied to the last two lines.
         * Node that fully encloses these lines is binary expression 'a ||...'.
         * Initial indentation for this node will be 0.
         * Binary expressions don't introduce new indentation scopes, however it is possible
         * that some parent node on the same line does - like if statement in this case.
         * Note that we are considering parents only from the same line with initial node -
         * if parent is on the different line - its delta was already contributed
         * to the initial indentation.
         */
        function getOwnOrInheritedDelta(n, options, sourceFile) {
            var previousLine = -1 /* Unknown */;
            var child;
            while (n) {
                var line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line;
                if (previousLine !== -1 /* Unknown */ && line !== previousLine) {
                    break;
                }
                if (formatting.SmartIndenter.shouldIndentChildNode(n, child)) {
                    return options.indentSize;
                }
                previousLine = line;
                child = n;
                n = n.parent;
            }
            return 0;
        }
        /* @internal */
        function formatNodeGivenIndentation(node, sourceFileLike, languageVariant, initialIndentation, delta, rulesProvider) {
            var range = { pos: 0, end: sourceFileLike.text.length };
            return formatting.getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, function (scanner) { return formatSpanWorker(range, node, initialIndentation, delta, scanner, rulesProvider.getFormatOptions(), rulesProvider, 1 /* FormatSelection */, function (_) { return false; }, // assume that node does not have any errors
            sourceFileLike); });
        }
        formatting.formatNodeGivenIndentation = formatNodeGivenIndentation;
        function formatNodeLines(node, sourceFile, options, rulesProvider, requestKind) {
            if (!node) {
                return [];
            }
            var span = {
                pos: ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile),
                end: node.end
            };
            return formatSpan(span, sourceFile, options, rulesProvider, requestKind);
        }
        function formatSpan(originalRange, sourceFile, options, rulesProvider, requestKind) {
            // find the smallest node that fully wraps the range and compute the initial indentation for the node
            var enclosingNode = findEnclosingNode(originalRange, sourceFile);
            return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options), getOwnOrInheritedDelta(enclosingNode, options, sourceFile), scanner, options, rulesProvider, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); });
        }
        function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, options, rulesProvider, requestKind, rangeContainsError, sourceFile) {
            // formatting context is used by rules provider
            var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options);
            var previousRange;
            var previousParent;
            var previousRangeStartLine;
            var lastIndentedLine;
            var indentationOnLastIndentedLine;
            var edits = [];
            formattingScanner.advance();
            if (formattingScanner.isOnToken()) {
                var startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line;
                var undecoratedStartLine = startLine;
                if (enclosingNode.decorators) {
                    undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line;
                }
                processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta);
            }
            if (!formattingScanner.isOnToken()) {
                var leadingTrivia = formattingScanner.getCurrentLeadingTrivia();
                if (leadingTrivia) {
                    processTrivia(leadingTrivia, enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined);
                    trimTrailingWhitespacesForRemainingRange();
                }
            }
            return edits;
            // local functions
            /** Tries to compute the indentation for a list element.
             * If list element is not in range then
             * function will pick its actual indentation
             * so it can be pushed downstream as inherited indentation.
             * If list element is in the range - its indentation will be equal
             * to inherited indentation from its predecessors.
             */
            function tryComputeIndentationForListItem(startPos, endPos, parentStartLine, range, inheritedIndentation) {
                if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos) ||
                    ts.rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) {
                    if (inheritedIndentation !== -1 /* Unknown */) {
                        return inheritedIndentation;
                    }
                }
                else {
                    var startLine = sourceFile.getLineAndCharacterOfPosition(startPos).line;
                    var startLinePosition = ts.getLineStartPositionForPosition(startPos, sourceFile);
                    var column = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options);
                    if (startLine !== parentStartLine || startPos === column) {
                        // Use the base indent size if it is greater than
                        // the indentation of the inherited predecessor.
                        var baseIndentSize = formatting.SmartIndenter.getBaseIndentation(options);
                        return baseIndentSize > column ? baseIndentSize : column;
                    }
                }
                return -1 /* Unknown */;
            }
            function computeIndentation(node, startLine, inheritedIndentation, parent, parentDynamicIndentation, effectiveParentStartLine) {
                var indentation = inheritedIndentation;
                var delta = formatting.SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
                if (effectiveParentStartLine === startLine) {
                    // if node is located on the same line with the parent
                    // - inherit indentation from the parent
                    // - push children if either parent of node itself has non-zero delta
                    indentation = startLine === lastIndentedLine
                        ? indentationOnLastIndentedLine
                        : parentDynamicIndentation.getIndentation();
                    delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta);
                }
                else if (indentation === -1 /* Unknown */) {
                    if (formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
                        indentation = parentDynamicIndentation.getIndentation();
                    }
                    else {
                        indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node);
                    }
                }
                return {
                    indentation: indentation,
                    delta: delta
                };
            }
            function getFirstNonDecoratorTokenOfNode(node) {
                if (node.modifiers && node.modifiers.length) {
                    return node.modifiers[0].kind;
                }
                switch (node.kind) {
                    case 229 /* ClassDeclaration */: return 75 /* ClassKeyword */;
                    case 230 /* InterfaceDeclaration */: return 109 /* InterfaceKeyword */;
                    case 228 /* FunctionDeclaration */: return 89 /* FunctionKeyword */;
                    case 232 /* EnumDeclaration */: return 232 /* EnumDeclaration */;
                    case 153 /* GetAccessor */: return 125 /* GetKeyword */;
                    case 154 /* SetAccessor */: return 135 /* SetKeyword */;
                    case 151 /* MethodDeclaration */:
                        if (node.asteriskToken) {
                            return 39 /* AsteriskToken */;
                        }
                    // falls through
                    case 149 /* PropertyDeclaration */:
                    case 146 /* Parameter */:
                        return ts.getNameOfDeclaration(node).kind;
                }
            }
            function getDynamicIndentation(node, nodeStartLine, indentation, delta) {
                return {
                    getIndentationForComment: function (kind, tokenIndentation, container) {
                        switch (kind) {
                            // preceding comment to the token that closes the indentation scope inherits the indentation from the scope
                            // ..  {
                            //     // comment
                            // }
                            case 18 /* CloseBraceToken */:
                            case 22 /* CloseBracketToken */:
                            case 20 /* CloseParenToken */:
                                return indentation + getEffectiveDelta(delta, container);
                        }
                        return tokenIndentation !== -1 /* Unknown */ ? tokenIndentation : indentation;
                    },
                    getIndentationForToken: function (line, kind, container) {
                        if (nodeStartLine !== line && node.decorators) {
                            if (kind === getFirstNonDecoratorTokenOfNode(node)) {
                                // if this token is the first token following the list of decorators, we do not need to indent
                                return indentation;
                            }
                        }
                        switch (kind) {
                            // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
                            case 17 /* OpenBraceToken */:
                            case 18 /* CloseBraceToken */:
                            case 19 /* OpenParenToken */:
                            case 20 /* CloseParenToken */:
                            case 82 /* ElseKeyword */:
                            case 106 /* WhileKeyword */:
                            case 57 /* AtToken */:
                                return indentation;
                            case 41 /* SlashToken */:
                            case 29 /* GreaterThanToken */: {
                                if (container.kind === 251 /* JsxOpeningElement */ ||
                                    container.kind === 252 /* JsxClosingElement */ ||
                                    container.kind === 250 /* JsxSelfClosingElement */) {
                                    return indentation;
                                }
                                break;
                            }
                            case 21 /* OpenBracketToken */:
                            case 22 /* CloseBracketToken */: {
                                if (container.kind !== 172 /* MappedType */) {
                                    return indentation;
                                }
                                break;
                            }
                        }
                        // if token line equals to the line of containing node (this is a first token in the node) - use node indentation
                        return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation;
                    },
                    getIndentation: function () { return indentation; },
                    getDelta: function (child) { return getEffectiveDelta(delta, child); },
                    recomputeIndentation: function (lineAdded) {
                        if (node.parent && formatting.SmartIndenter.shouldIndentChildNode(node.parent, node)) {
                            if (lineAdded) {
                                indentation += options.indentSize;
                            }
                            else {
                                indentation -= options.indentSize;
                            }
                            if (formatting.SmartIndenter.shouldIndentChildNode(node)) {
                                delta = options.indentSize;
                            }
                            else {
                                delta = 0;
                            }
                        }
                    }
                };
                function getEffectiveDelta(delta, child) {
                    // Delta value should be zero when the node explicitly prevents indentation of the child node
                    return formatting.SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0;
                }
            }
            function processNode(node, contextNode, nodeStartLine, undecoratedNodeStartLine, indentation, delta) {
                if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) {
                    return;
                }
                var nodeDynamicIndentation = getDynamicIndentation(node, nodeStartLine, indentation, delta);
                // a useful observations when tracking context node
                //        /
                //      [a]
                //   /   |   \
                //  [b] [c] [d]
                // node 'a' is a context node for nodes 'b', 'c', 'd'
                // except for the leftmost leaf token in [b] - in this case context node ('e') is located somewhere above 'a'
                // this rule can be applied recursively to child nodes of 'a'.
                //
                // context node is set to parent node value after processing every child node
                // context node is set to parent of the token after processing every token
                var childContextNode = contextNode;
                // if there are any tokens that logically belong to node and interleave child nodes
                // such tokens will be consumed in processChildNode for for the child that follows them
                ts.forEachChild(node, function (child) {
                    processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false);
                }, function (nodes) {
                    processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation);
                });
                // proceed any tokens in the node that are located after child nodes
                while (formattingScanner.isOnToken()) {
                    var tokenInfo = formattingScanner.readTokenInfo(node);
                    if (tokenInfo.token.end > node.end) {
                        break;
                    }
                    consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node);
                }
                function processChildNode(child, inheritedIndentation, parent, parentDynamicIndentation, parentStartLine, undecoratedParentStartLine, isListItem, isFirstListItem) {
                    var childStartPos = child.getStart(sourceFile);
                    var childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line;
                    var undecoratedChildStartLine = childStartLine;
                    if (child.decorators) {
                        undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(child, sourceFile)).line;
                    }
                    // if child is a list item - try to get its indentation, only if parent is within the original range.
                    var childIndentationAmount = -1 /* Unknown */;
                    if (isListItem && ts.rangeContainsRange(originalRange, parent)) {
                        childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation);
                        if (childIndentationAmount !== -1 /* Unknown */) {
                            inheritedIndentation = childIndentationAmount;
                        }
                    }
                    // child node is outside the target range - do not dive inside
                    if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) {
                        if (child.end < originalRange.pos) {
                            formattingScanner.skipToEndOf(child);
                        }
                        return inheritedIndentation;
                    }
                    if (child.getFullWidth() === 0) {
                        return inheritedIndentation;
                    }
                    while (formattingScanner.isOnToken()) {
                        // proceed any parent tokens that are located prior to child.getStart()
                        var tokenInfo = formattingScanner.readTokenInfo(node);
                        if (tokenInfo.token.end > childStartPos) {
                            // stop when formatting scanner advances past the beginning of the child
                            break;
                        }
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, node);
                    }
                    if (!formattingScanner.isOnToken()) {
                        return inheritedIndentation;
                    }
                    // JSX text shouldn't affect indenting
                    if (ts.isToken(child) && child.kind !== 10 /* JsxText */) {
                        // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules
                        var tokenInfo = formattingScanner.readTokenInfo(child);
                        ts.Debug.assert(tokenInfo.token.end === child.end, "Token end is child end");
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child);
                        return inheritedIndentation;
                    }
                    var effectiveParentStartLine = child.kind === 147 /* Decorator */ ? childStartLine : undecoratedParentStartLine;
                    var childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine);
                    processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
                    childContextNode = node;
                    if (isFirstListItem && parent.kind === 177 /* ArrayLiteralExpression */ && inheritedIndentation === -1 /* Unknown */) {
                        inheritedIndentation = childIndentation.indentation;
                    }
                    return inheritedIndentation;
                }
                function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) {
                    ts.Debug.assert(ts.isNodeArray(nodes));
                    var listStartToken = getOpenTokenForList(parent, nodes);
                    var listEndToken = getCloseTokenForOpenToken(listStartToken);
                    var listDynamicIndentation = parentDynamicIndentation;
                    var startLine = parentStartLine;
                    if (listStartToken !== 0 /* Unknown */) {
                        // introduce a new indentation scope for lists (including list start and end tokens)
                        while (formattingScanner.isOnToken()) {
                            var tokenInfo = formattingScanner.readTokenInfo(parent);
                            if (tokenInfo.token.end > nodes.pos) {
                                // stop when formatting scanner moves past the beginning of node list
                                break;
                            }
                            else if (tokenInfo.token.kind === listStartToken) {
                                // consume list start token
                                startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line;
                                var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, parentStartLine);
                                listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation_1.indentation, indentation_1.delta);
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
                            }
                            else {
                                // consume any tokens that precede the list as child elements of 'node' using its indentation scope
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
                            }
                        }
                    }
                    var inheritedIndentation = -1 /* Unknown */;
                    for (var i = 0; i < nodes.length; i++) {
                        var child = nodes[i];
                        inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0);
                    }
                    if (listEndToken !== 0 /* Unknown */) {
                        if (formattingScanner.isOnToken()) {
                            var tokenInfo = formattingScanner.readTokenInfo(parent);
                            // consume the list end token only if it is still belong to the parent
                            // there might be the case when current token matches end token but does not considered as one
                            // function (x: function) <--
                            // without this check close paren will be interpreted as list end token for function expression which is wrong
                            if (tokenInfo.token.kind === listEndToken && ts.rangeContainsRange(parent, tokenInfo.token)) {
                                // consume list end token
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
                            }
                        }
                    }
                }
                function consumeTokenAndAdvanceScanner(currentTokenInfo, parent, dynamicIndentation, container) {
                    ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token));
                    var lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();
                    var indentToken = false;
                    if (currentTokenInfo.leadingTrivia) {
                        processTrivia(currentTokenInfo.leadingTrivia, parent, childContextNode, dynamicIndentation);
                    }
                    var lineAdded;
                    var isTokenInRange = ts.rangeContainsRange(originalRange, currentTokenInfo.token);
                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(currentTokenInfo.token.pos);
                    if (isTokenInRange) {
                        var rangeHasError = rangeContainsError(currentTokenInfo.token);
                        // save previousRange since processRange will overwrite this value with current one
                        var savePreviousRange = previousRange;
                        lineAdded = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation);
                        if (rangeHasError) {
                            // do not indent comments\token if token range overlaps with some error
                            indentToken = false;
                        }
                        else {
                            if (lineAdded !== undefined) {
                                indentToken = lineAdded;
                            }
                            else {
                                // indent token only if end line of previous range does not match start line of the token
                                var prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line;
                                indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
                            }
                        }
                    }
                    if (currentTokenInfo.trailingTrivia) {
                        processTrivia(currentTokenInfo.trailingTrivia, parent, childContextNode, dynamicIndentation);
                    }
                    if (indentToken) {
                        var tokenIndentation = (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) ?
                            dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container) :
                            -1 /* Unknown */;
                        var indentNextTokenOrTrivia = true;
                        if (currentTokenInfo.leadingTrivia) {
                            var commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container);
                            for (var _i = 0, _a = currentTokenInfo.leadingTrivia; _i < _a.length; _i++) {
                                var triviaItem = _a[_i];
                                var triviaInRange = ts.rangeContainsRange(originalRange, triviaItem);
                                switch (triviaItem.kind) {
                                    case 3 /* MultiLineCommentTrivia */:
                                        if (triviaInRange) {
                                            indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
                                        }
                                        indentNextTokenOrTrivia = false;
                                        break;
                                    case 2 /* SingleLineCommentTrivia */:
                                        if (indentNextTokenOrTrivia && triviaInRange) {
                                            insertIndentation(triviaItem.pos, commentIndentation, /*lineAdded*/ false);
                                        }
                                        indentNextTokenOrTrivia = false;
                                        break;
                                    case 4 /* NewLineTrivia */:
                                        indentNextTokenOrTrivia = true;
                                        break;
                                }
                            }
                        }
                        // indent token only if is it is in target range and does not overlap with any error ranges
                        if (tokenIndentation !== -1 /* Unknown */ && indentNextTokenOrTrivia) {
                            insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded);
                            lastIndentedLine = tokenStart.line;
                            indentationOnLastIndentedLine = tokenIndentation;
                        }
                    }
                    formattingScanner.advance();
                    childContextNode = parent;
                }
            }
            function processTrivia(trivia, parent, contextNode, dynamicIndentation) {
                for (var _i = 0, trivia_1 = trivia; _i < trivia_1.length; _i++) {
                    var triviaItem = trivia_1[_i];
                    if (ts.isComment(triviaItem.kind) && ts.rangeContainsRange(originalRange, triviaItem)) {
                        var triviaItemStart = sourceFile.getLineAndCharacterOfPosition(triviaItem.pos);
                        processRange(triviaItem, triviaItemStart, parent, contextNode, dynamicIndentation);
                    }
                }
            }
            function processRange(range, rangeStart, parent, contextNode, dynamicIndentation) {
                var rangeHasError = rangeContainsError(range);
                var lineAdded;
                if (!rangeHasError) {
                    if (!previousRange) {
                        // trim whitespaces starting from the beginning of the span up to the current line
                        var originalStart = sourceFile.getLineAndCharacterOfPosition(originalRange.pos);
                        trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line);
                    }
                    else {
                        lineAdded =
                            processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation);
                    }
                }
                previousRange = range;
                previousParent = parent;
                previousRangeStartLine = rangeStart.line;
                return lineAdded;
            }
            function processPair(currentItem, currentStartLine, currentParent, previousItem, previousStartLine, previousParent, contextNode, dynamicIndentation) {
                formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode);
                var rule = rulesProvider.getRulesMap().GetRule(formattingContext);
                var trimTrailingWhitespaces;
                var lineAdded;
                if (rule) {
                    applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
                    if (rule.Operation.Action & (2 /* Space */ | 8 /* Delete */) && currentStartLine !== previousStartLine) {
                        lineAdded = false;
                        // Handle the case where the next line is moved to be the end of this line.
                        // In this case we don't indent the next line in the next pass.
                        if (currentParent.getStart(sourceFile) === currentItem.pos) {
                            dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
                        }
                    }
                    else if (rule.Operation.Action & 4 /* NewLine */ && currentStartLine === previousStartLine) {
                        lineAdded = true;
                        // Handle the case where token2 is moved to the new line.
                        // In this case we indent token2 in the next pass but we set
                        // sameLineIndent flag to notify the indenter that the indentation is within the line.
                        if (currentParent.getStart(sourceFile) === currentItem.pos) {
                            dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true);
                        }
                    }
                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
                    trimTrailingWhitespaces = !(rule.Operation.Action & 8 /* Delete */) && rule.Flag !== 1 /* CanDeleteNewLines */;
                }
                else {
                    trimTrailingWhitespaces = true;
                }
                if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) {
                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
                    trimTrailingWhitespacesForLines(previousStartLine, currentStartLine, previousItem);
                }
                return lineAdded;
            }
            function insertIndentation(pos, indentation, lineAdded) {
                var indentationString = getIndentationString(indentation, options);
                if (lineAdded) {
                    // new line is added before the token by the formatting rules
                    // insert indentation string at the very beginning of the token
                    recordReplace(pos, 0, indentationString);
                }
                else {
                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(pos);
                    var startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile);
                    if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) {
                        recordReplace(startLinePosition, tokenStart.character, indentationString);
                    }
                }
            }
            function characterToColumn(startLinePosition, characterInLine) {
                var column = 0;
                for (var i = 0; i < characterInLine; i++) {
                    if (sourceFile.text.charCodeAt(startLinePosition + i) === 9 /* tab */) {
                        column += options.tabSize - column % options.tabSize;
                    }
                    else {
                        column++;
                    }
                }
                return column;
            }
            function indentationIsDifferent(indentationString, startLinePosition) {
                return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
            }
            function indentMultilineComment(commentRange, indentation, firstLineIsIndented) {
                // split comment in lines
                var startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
                var parts;
                if (startLine === endLine) {
                    if (!firstLineIsIndented) {
                        // treat as single line comment
                        insertIndentation(commentRange.pos, indentation, /*lineAdded*/ false);
                    }
                    return;
                }
                else {
                    parts = [];
                    var startPos = commentRange.pos;
                    for (var line = startLine; line < endLine; line++) {
                        var endOfLine = ts.getEndLinePosition(line, sourceFile);
                        parts.push({ pos: startPos, end: endOfLine });
                        startPos = ts.getStartPositionOfLine(line + 1, sourceFile);
                    }
                    parts.push({ pos: startPos, end: commentRange.end });
                }
                var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile);
                var nonWhitespaceColumnInFirstPart = formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options);
                if (indentation === nonWhitespaceColumnInFirstPart.column) {
                    return;
                }
                var startIndex = 0;
                if (firstLineIsIndented) {
                    startIndex = 1;
                    startLine++;
                }
                // shift all parts on the delta size
                var delta = indentation - nonWhitespaceColumnInFirstPart.column;
                for (var i = startIndex; i < parts.length; i++, startLine++) {
                    var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile);
                    var nonWhitespaceCharacterAndColumn = i === 0
                        ? nonWhitespaceColumnInFirstPart
                        : formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options);
                    var newIndentation = nonWhitespaceCharacterAndColumn.column + delta;
                    if (newIndentation > 0) {
                        var indentationString = getIndentationString(newIndentation, options);
                        recordReplace(startLinePos_1, nonWhitespaceCharacterAndColumn.character, indentationString);
                    }
                    else {
                        recordDelete(startLinePos_1, nonWhitespaceCharacterAndColumn.character);
                    }
                }
            }
            function trimTrailingWhitespacesForLines(line1, line2, range) {
                for (var line = line1; line < line2; line++) {
                    var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
                    var lineEndPosition = ts.getEndLinePosition(line, sourceFile);
                    // do not trim whitespaces in comments or template expression
                    if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
                        continue;
                    }
                    var whitespaceStart = getTrailingWhitespaceStartPosition(lineStartPosition, lineEndPosition);
                    if (whitespaceStart !== -1) {
                        ts.Debug.assert(whitespaceStart === lineStartPosition || !ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1)));
                        recordDelete(whitespaceStart, lineEndPosition + 1 - whitespaceStart);
                    }
                }
            }
            /**
             * @param start The position of the first character in range
             * @param end The position of the last character in range
             */
            function getTrailingWhitespaceStartPosition(start, end) {
                var pos = end;
                while (pos >= start && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) {
                    pos--;
                }
                if (pos !== end) {
                    return pos + 1;
                }
                return -1;
            }
            /**
             * Trimming will be done for lines after the previous range
             */
            function trimTrailingWhitespacesForRemainingRange() {
                var startPosition = previousRange ? previousRange.end : originalRange.pos;
                var startLine = sourceFile.getLineAndCharacterOfPosition(startPosition).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(originalRange.end).line;
                trimTrailingWhitespacesForLines(startLine, endLine + 1, previousRange);
            }
            function newTextChange(start, len, newText) {
                return { span: ts.createTextSpan(start, len), newText: newText };
            }
            function recordDelete(start, len) {
                if (len) {
                    edits.push(newTextChange(start, len, ""));
                }
            }
            function recordReplace(start, len, newText) {
                if (len || newText) {
                    edits.push(newTextChange(start, len, newText));
                }
            }
            function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) {
                switch (rule.Operation.Action) {
                    case 1 /* Ignore */:
                        // no action required
                        return;
                    case 8 /* Delete */:
                        if (previousRange.end !== currentRange.pos) {
                            // delete characters starting from t1.end up to t2.pos exclusive
                            recordDelete(previousRange.end, currentRange.pos - previousRange.end);
                        }
                        break;
                    case 4 /* NewLine */:
                        // exit early if we on different lines and rule cannot change number of newlines
                        // if line1 and line2 are on subsequent lines then no edits are required - ok to exit
                        // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines
                        if (rule.Flag !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                            return;
                        }
                        // edit should not be applied if we have one line feed between elements
                        var lineDelta = currentStartLine - previousStartLine;
                        if (lineDelta !== 1) {
                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.newLineCharacter);
                        }
                        break;
                    case 2 /* Space */:
                        // exit early if we on different lines and rule cannot change number of newlines
                        if (rule.Flag !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                            return;
                        }
                        var posDelta = currentRange.pos - previousRange.end;
                        if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== 32 /* space */) {
                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, " ");
                        }
                        break;
                }
            }
        }
        /**
         * @param precedingToken pass `null` if preceding token was already computed and result was `undefined`.
         */
        function getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine, precedingToken, // tslint:disable-line:no-null-keyword
            tokenAtPosition, predicate) {
            if (tokenAtPosition === void 0) { tokenAtPosition = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); }
            var tokenStart = tokenAtPosition.getStart(sourceFile);
            if (tokenStart <= position && position < tokenAtPosition.getEnd()) {
                return undefined;
            }
            if (precedingToken === undefined) {
                precedingToken = ts.findPrecedingToken(position, sourceFile);
            }
            // Between two consecutive tokens, all comments are either trailing on the former
            // or leading on the latter (and none are in both lists).
            var trailingRangesOfPreviousToken = precedingToken && ts.getTrailingCommentRanges(sourceFile.text, precedingToken.end);
            var leadingCommentRangesOfNextToken = ts.getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile);
            var commentRanges = trailingRangesOfPreviousToken && leadingCommentRangesOfNextToken ?
                trailingRangesOfPreviousToken.concat(leadingCommentRangesOfNextToken) :
                trailingRangesOfPreviousToken || leadingCommentRangesOfNextToken;
            if (commentRanges) {
                for (var _i = 0, commentRanges_1 = commentRanges; _i < commentRanges_1.length; _i++) {
                    var range = commentRanges_1[_i];
                    // The end marker of a single-line comment does not include the newline character.
                    // With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position):
                    //
                    //    // asdf   ^\n
                    //
                    // But for closed multi-line comments, we don't want to be inside the comment in the following case:
                    //
                    //    /* asdf */^
                    //
                    // However, unterminated multi-line comments *do* contain their end.
                    //
                    // Internally, we represent the end of the comment at the newline and closing '/', respectively.
                    //
                    if ((range.pos < position && position < range.end ||
                        position === range.end && (range.kind === 2 /* SingleLineCommentTrivia */ || position === sourceFile.getFullWidth()))) {
                        return (range.kind === 3 /* MultiLineCommentTrivia */ || !onlyMultiLine) && (!predicate || predicate(range)) ? range : undefined;
                    }
                }
            }
            return undefined;
        }
        formatting.getRangeOfEnclosingComment = getRangeOfEnclosingComment;
        function getOpenTokenForList(node, list) {
            switch (node.kind) {
                case 152 /* Constructor */:
                case 228 /* FunctionDeclaration */:
                case 186 /* FunctionExpression */:
                case 151 /* MethodDeclaration */:
                case 150 /* MethodSignature */:
                case 187 /* ArrowFunction */:
                    if (node.typeParameters === list) {
                        return 27 /* LessThanToken */;
                    }
                    else if (node.parameters === list) {
                        return 19 /* OpenParenToken */;
                    }
                    break;
                case 181 /* CallExpression */:
                case 182 /* NewExpression */:
                    if (node.typeArguments === list) {
                        return 27 /* LessThanToken */;
                    }
                    else if (node.arguments === list) {
                        return 19 /* OpenParenToken */;
                    }
                    break;
                case 159 /* TypeReference */:
                    if (node.typeArguments === list) {
                        return 27 /* LessThanToken */;
                    }
            }
            return 0 /* Unknown */;
        }
        function getCloseTokenForOpenToken(kind) {
            switch (kind) {
                case 19 /* OpenParenToken */:
                    return 20 /* CloseParenToken */;
                case 27 /* LessThanToken */:
                    return 29 /* GreaterThanToken */;
            }
            return 0 /* Unknown */;
        }
        var internedSizes;
        var internedTabsIndentation;
        var internedSpacesIndentation;
        function getIndentationString(indentation, options) {
            // reset interned strings if FormatCodeOptions were changed
            var resetInternedStrings = !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize);
            if (resetInternedStrings) {
                internedSizes = { tabSize: options.tabSize, indentSize: options.indentSize };
                internedTabsIndentation = internedSpacesIndentation = undefined;
            }
            if (!options.convertTabsToSpaces) {
                var tabs = Math.floor(indentation / options.tabSize);
                var spaces = indentation - tabs * options.tabSize;
                var tabString = void 0;
                if (!internedTabsIndentation) {
                    internedTabsIndentation = [];
                }
                if (internedTabsIndentation[tabs] === undefined) {
                    internedTabsIndentation[tabs] = tabString = repeat("\t", tabs);
                }
                else {
                    tabString = internedTabsIndentation[tabs];
                }
                return spaces ? tabString + repeat(" ", spaces) : tabString;
            }
            else {
                var spacesString = void 0;
                var quotient = Math.floor(indentation / options.indentSize);
                var remainder = indentation % options.indentSize;
                if (!internedSpacesIndentation) {
                    internedSpacesIndentation = [];
                }
                if (internedSpacesIndentation[quotient] === undefined) {
                    spacesString = repeat(" ", options.indentSize * quotient);
                    internedSpacesIndentation[quotient] = spacesString;
                }
                else {
                    spacesString = internedSpacesIndentation[quotient];
                }
                return remainder ? spacesString + repeat(" ", remainder) : spacesString;
            }
            function repeat(value, count) {
                var s = "";
                for (var i = 0; i < count; i++) {
                    s += value;
                }
                return s;
            }
        }
        formatting.getIndentationString = getIndentationString;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
///<reference path='..\services.ts' />
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var SmartIndenter;
        (function (SmartIndenter) {
            var Value;
            (function (Value) {
                Value[Value["Unknown"] = -1] = "Unknown";
            })(Value || (Value = {}));
            /**
             * @param assumeNewLineBeforeCloseBrace
             * `false` when called on text from a real source file.
             * `true` when we need to assume `position` is on a newline.
             *
             * This is useful for codefixes. Consider
             * ```
             * function f() {
             * |}
             * ```
             * with `position` at `|`.
             *
             * When inserting some text after an open brace, we would like to get indentation as if a newline was already there.
             * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior.
             */
            function getIndentation(position, sourceFile, options, assumeNewLineBeforeCloseBrace) {
                if (assumeNewLineBeforeCloseBrace === void 0) { assumeNewLineBeforeCloseBrace = false; }
                if (position > sourceFile.text.length) {
                    return getBaseIndentation(options); // past EOF
                }
                // no indentation when the indent style is set to none,
                // so we can return fast
                if (options.indentStyle === ts.IndentStyle.None) {
                    return 0;
                }
                var precedingToken = ts.findPrecedingToken(position, sourceFile);
                var enclosingCommentRange = formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ true, precedingToken || null); // tslint:disable-line:no-null-keyword
                if (enclosingCommentRange) {
                    var previousLine = ts.getLineAndCharacterOfPosition(sourceFile, position).line - 1;
                    var commentStartLine = ts.getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line;
                    ts.Debug.assert(commentStartLine >= 0);
                    if (previousLine <= commentStartLine) {
                        return findFirstNonWhitespaceColumn(ts.getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options);
                    }
                    var startPostionOfLine = ts.getStartPositionOfLine(previousLine, sourceFile);
                    var _a = findFirstNonWhitespaceCharacterAndColumn(startPostionOfLine, position, sourceFile, options), column = _a.column, character = _a.character;
                    if (column === 0) {
                        return column;
                    }
                    var firstNonWhitespaceCharacterCode = sourceFile.text.charCodeAt(startPostionOfLine + character);
                    return firstNonWhitespaceCharacterCode === 42 /* asterisk */ ? column - 1 : column;
                }
                if (!precedingToken) {
                    return getBaseIndentation(options);
                }
                // no indentation in string \regex\template literals
                var precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
                if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && position < precedingToken.end) {
                    return 0;
                }
                var lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
                // indentation is first non-whitespace character in a previous line
                // for block indentation, we should look for a line which contains something that's not
                // whitespace.
                if (options.indentStyle === ts.IndentStyle.Block) {
                    // move backwards until we find a line with a non-whitespace character,
                    // then find the first non-whitespace character for that line.
                    var current_1 = position;
                    while (current_1 > 0) {
                        var char = sourceFile.text.charCodeAt(current_1);
                        if (!ts.isWhiteSpaceLike(char)) {
                            break;
                        }
                        current_1--;
                    }
                    var lineStart = ts.getLineStartPositionForPosition(current_1, sourceFile);
                    return SmartIndenter.findFirstNonWhitespaceColumn(lineStart, current_1, sourceFile, options);
                }
                if (precedingToken.kind === 26 /* CommaToken */ && precedingToken.parent.kind !== 194 /* BinaryExpression */) {
                    // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
                    var actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation;
                    }
                }
                // try to find node that can contribute to indentation and includes 'position' starting from 'precedingToken'
                // if such node is found - compute initial indentation for 'position' inside this node
                var previous;
                var current = precedingToken;
                var currentStart;
                var indentationDelta;
                while (current) {
                    if (ts.positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous)) {
                        currentStart = getStartLineAndCharacterForNode(current, sourceFile);
                        var nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile);
                        if (nextTokenKind !== 0 /* Unknown */) {
                            // handle cases when codefix is about to be inserted before the close brace
                            indentationDelta = assumeNewLineBeforeCloseBrace && nextTokenKind === 2 /* CloseBrace */ ? options.indentSize : 0;
                        }
                        else {
                            indentationDelta = lineAtPosition !== currentStart.line ? options.indentSize : 0;
                        }
                        break;
                    }
                    // check if current node is a list item - if yes, take indentation from it
                    var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation;
                    }
                    actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation + options.indentSize;
                    }
                    previous = current;
                    current = current.parent;
                }
                if (!current) {
                    // no parent was found - return the base indentation of the SourceFile
                    return getBaseIndentation(options);
                }
                return getIndentationForNodeWorker(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, options);
            }
            SmartIndenter.getIndentation = getIndentation;
            function getIndentationForNode(n, ignoreActualIndentationRange, sourceFile, options) {
                var start = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
                return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, options);
            }
            SmartIndenter.getIndentationForNode = getIndentationForNode;
            function getBaseIndentation(options) {
                return options.baseIndentSize || 0;
            }
            SmartIndenter.getBaseIndentation = getBaseIndentation;
            function getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, options) {
                var parent = current.parent;
                var containingListOrParentStart;
                // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if
                // * parent and child nodes start on the same line, or
                // * parent is an IfStatement and child starts on the same line as an 'else clause'.
                while (parent) {
                    var useActualIndentation = true;
                    if (ignoreActualIndentationRange) {
                        var start = current.getStart(sourceFile);
                        useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end;
                    }
                    if (useActualIndentation) {
                        // check if current node is a list item - if yes, take indentation from it
                        var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                    }
                    containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile);
                    var parentAndChildShareLine = containingListOrParentStart.line === currentStart.line ||
                        childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
                    if (useActualIndentation) {
                        // try to fetch actual indentation for current node from source text
                        var actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                        actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                    }
                    // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
                    if (shouldIndentChildNode(parent, current) && !parentAndChildShareLine) {
                        indentationDelta += options.indentSize;
                    }
                    // In our AST, a call argument's `parent` is the call-expression, not the argument list.
                    // We would like to increase indentation based on the relationship between an argument and its argument-list,
                    // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list.
                    // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression
                    // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation.
                    //
                    // Instead, when at an argument, we unspoof the starting position of the enclosing call expression
                    // *after* applying indentation for the argument.
                    var useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile);
                    current = parent;
                    parent = current.parent;
                    currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : containingListOrParentStart;
                }
                return indentationDelta + getBaseIndentation(options);
            }
            function getContainingListOrParentStart(parent, child, sourceFile) {
                var containingList = getContainingList(child, sourceFile);
                var startPos = containingList ? containingList.pos : parent.getStart(sourceFile);
                return sourceFile.getLineAndCharacterOfPosition(startPos);
            }
            /*
             * Function returns Value.Unknown if indentation cannot be determined
             */
            function getActualIndentationForListItemBeforeComma(commaToken, sourceFile, options) {
                // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
                var commaItemInfo = ts.findListItemInfo(commaToken);
                if (commaItemInfo && commaItemInfo.listItemIndex > 0) {
                    return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
                }
                else {
                    // handle broken code gracefully
                    return -1 /* Unknown */;
                }
            }
            /*
             * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression)
             */
            function getActualIndentationForNode(current, parent, currentLineAndChar, parentAndChildShareLine, sourceFile, options) {
                // actual indentation is used for statements\declarations if one of cases below is true:
                // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
                // - parent and child are not on the same line
                var useActualIndentation = (ts.isDeclaration(current) || ts.isStatementButNotDeclaration(current)) &&
                    (parent.kind === 265 /* SourceFile */ || !parentAndChildShareLine);
                if (!useActualIndentation) {
                    return -1 /* Unknown */;
                }
                return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
            }
            var NextTokenKind;
            (function (NextTokenKind) {
                NextTokenKind[NextTokenKind["Unknown"] = 0] = "Unknown";
                NextTokenKind[NextTokenKind["OpenBrace"] = 1] = "OpenBrace";
                NextTokenKind[NextTokenKind["CloseBrace"] = 2] = "CloseBrace";
            })(NextTokenKind || (NextTokenKind = {}));
            function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) {
                var nextToken = ts.findNextToken(precedingToken, current);
                if (!nextToken) {
                    return 0 /* Unknown */;
                }
                if (nextToken.kind === 17 /* OpenBraceToken */) {
                    // open braces are always indented at the parent level
                    return 1 /* OpenBrace */;
                }
                else if (nextToken.kind === 18 /* CloseBraceToken */) {
                    // close braces are indented at the parent level if they are located on the same line with cursor
                    // this means that if new line will be added at $ position, this case will be indented
                    // class A {
                    //    $
                    // }
                    /// and this one - not
                    // class A {
                    // $}
                    var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
                    return lineAtPosition === nextTokenStartLine ? 2 /* CloseBrace */ : 0 /* Unknown */;
                }
                return 0 /* Unknown */;
            }
            function getStartLineAndCharacterForNode(n, sourceFile) {
                return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
            }
            function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, child, childStartLine, sourceFile) {
                if (!(ts.isCallExpression(parent) && ts.contains(parent.arguments, child))) {
                    return false;
                }
                var expressionOfCallExpressionEnd = parent.expression.getEnd();
                var expressionOfCallExpressionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line;
                return expressionOfCallExpressionEndLine === childStartLine;
            }
            SmartIndenter.isArgumentAndStartLineOverlapsExpressionBeingCalled = isArgumentAndStartLineOverlapsExpressionBeingCalled;
            function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) {
                if (parent.kind === 211 /* IfStatement */ && parent.elseStatement === child) {
                    var elseKeyword = ts.findChildOfKind(parent, 82 /* ElseKeyword */, sourceFile);
                    ts.Debug.assert(elseKeyword !== undefined);
                    var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
                    return elseKeywordStartLine === childStartLine;
                }
                return false;
            }
            SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement;
            function getListIfStartEndIsInListRange(list, start, end) {
                return list && ts.rangeContainsStartEnd(list, start, end) ? list : undefined;
            }
            function getContainingList(node, sourceFile) {
                if (node.parent) {
                    switch (node.parent.kind) {
                        case 159 /* TypeReference */:
                            return getListIfStartEndIsInListRange(node.parent.typeArguments, node.getStart(sourceFile), node.getEnd());
                        case 178 /* ObjectLiteralExpression */:
                            return node.parent.properties;
                        case 177 /* ArrayLiteralExpression */:
                            return node.parent.elements;
                        case 228 /* FunctionDeclaration */:
                        case 186 /* FunctionExpression */:
                        case 187 /* ArrowFunction */:
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                        case 155 /* CallSignature */:
                        case 152 /* Constructor */:
                        case 161 /* ConstructorType */:
                        case 156 /* ConstructSignature */: {
                            var start = node.getStart(sourceFile);
                            return getListIfStartEndIsInListRange(node.parent.typeParameters, start, node.getEnd()) ||
                                getListIfStartEndIsInListRange(node.parent.parameters, start, node.getEnd());
                        }
                        case 229 /* ClassDeclaration */:
                            return getListIfStartEndIsInListRange(node.parent.typeParameters, node.getStart(sourceFile), node.getEnd());
                        case 182 /* NewExpression */:
                        case 181 /* CallExpression */: {
                            var start = node.getStart(sourceFile);
                            return getListIfStartEndIsInListRange(node.parent.typeArguments, start, node.getEnd()) ||
                                getListIfStartEndIsInListRange(node.parent.arguments, start, node.getEnd());
                        }
                        case 227 /* VariableDeclarationList */:
                            return getListIfStartEndIsInListRange(node.parent.declarations, node.getStart(sourceFile), node.getEnd());
                        case 241 /* NamedImports */:
                        case 245 /* NamedExports */:
                            return getListIfStartEndIsInListRange(node.parent.elements, node.getStart(sourceFile), node.getEnd());
                    }
                }
                return undefined;
            }
            SmartIndenter.getContainingList = getContainingList;
            function getActualIndentationForListItem(node, sourceFile, options) {
                var containingList = getContainingList(node, sourceFile);
                return containingList ? getActualIndentationFromList(containingList) : -1 /* Unknown */;
                function getActualIndentationFromList(list) {
                    var index = ts.indexOf(list, node);
                    return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : -1 /* Unknown */;
                }
            }
            function getLineIndentationWhenExpressionIsInMultiLine(node, sourceFile, options) {
                // actual indentation should not be used when:
                // - node is close parenthesis - this is the end of the expression
                if (node.kind === 20 /* CloseParenToken */) {
                    return -1 /* Unknown */;
                }
                if (node.parent && ts.isCallOrNewExpression(node.parent) && node.parent.expression !== node) {
                    var fullCallOrNewExpression = node.parent.expression;
                    var startingExpression = getStartingExpression(fullCallOrNewExpression);
                    if (fullCallOrNewExpression === startingExpression) {
                        return -1 /* Unknown */;
                    }
                    var fullCallOrNewExpressionEnd = sourceFile.getLineAndCharacterOfPosition(fullCallOrNewExpression.end);
                    var startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end);
                    if (fullCallOrNewExpressionEnd.line === startingExpressionEnd.line) {
                        return -1 /* Unknown */;
                    }
                    return findColumnForFirstNonWhitespaceCharacterInLine(fullCallOrNewExpressionEnd, sourceFile, options);
                }
                return -1 /* Unknown */;
                function getStartingExpression(node) {
                    while (true) {
                        switch (node.kind) {
                            case 181 /* CallExpression */:
                            case 182 /* NewExpression */:
                            case 179 /* PropertyAccessExpression */:
                            case 180 /* ElementAccessExpression */:
                                node = node.expression;
                                break;
                            default:
                                return node;
                        }
                    }
                }
            }
            function deriveActualIndentationFromList(list, index, sourceFile, options) {
                ts.Debug.assert(index >= 0 && index < list.length);
                var node = list[index];
                // walk toward the start of the list starting from current node and check if the line is the same for all items.
                // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i]
                var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
                for (var i = index - 1; i >= 0; i--) {
                    if (list[i].kind === 26 /* CommaToken */) {
                        continue;
                    }
                    // skip list items that ends on the same line with the current list element
                    var prevEndLine = sourceFile.getLineAndCharacterOfPosition(list[i].end).line;
                    if (prevEndLine !== lineAndCharacter.line) {
                        return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
                    }
                    lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
                }
                return -1 /* Unknown */;
            }
            function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options) {
                var lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0);
                return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
            }
            /**
             * Character is the actual index of the character since the beginning of the line.
             * Column - position of the character after expanding tabs to spaces.
             * "0\t2$"
             * value of 'character' for '$' is 3
             * value of 'column' for '$' is 6 (assuming that tab size is 4)
             */
            function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) {
                var character = 0;
                var column = 0;
                for (var pos = startPos; pos < endPos; pos++) {
                    var ch = sourceFile.text.charCodeAt(pos);
                    if (!ts.isWhiteSpaceSingleLine(ch)) {
                        break;
                    }
                    if (ch === 9 /* tab */) {
                        column += options.tabSize + (column % options.tabSize);
                    }
                    else {
                        column++;
                    }
                    character++;
                }
                return { column: column, character: character };
            }
            SmartIndenter.findFirstNonWhitespaceCharacterAndColumn = findFirstNonWhitespaceCharacterAndColumn;
            function findFirstNonWhitespaceColumn(startPos, endPos, sourceFile, options) {
                return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column;
            }
            SmartIndenter.findFirstNonWhitespaceColumn = findFirstNonWhitespaceColumn;
            function nodeContentIsAlwaysIndented(kind) {
                switch (kind) {
                    case 210 /* ExpressionStatement */:
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 230 /* InterfaceDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 231 /* TypeAliasDeclaration */:
                    case 177 /* ArrayLiteralExpression */:
                    case 207 /* Block */:
                    case 234 /* ModuleBlock */:
                    case 178 /* ObjectLiteralExpression */:
                    case 163 /* TypeLiteral */:
                    case 172 /* MappedType */:
                    case 165 /* TupleType */:
                    case 235 /* CaseBlock */:
                    case 258 /* DefaultClause */:
                    case 257 /* CaseClause */:
                    case 185 /* ParenthesizedExpression */:
                    case 179 /* PropertyAccessExpression */:
                    case 181 /* CallExpression */:
                    case 182 /* NewExpression */:
                    case 208 /* VariableStatement */:
                    case 226 /* VariableDeclaration */:
                    case 243 /* ExportAssignment */:
                    case 219 /* ReturnStatement */:
                    case 195 /* ConditionalExpression */:
                    case 175 /* ArrayBindingPattern */:
                    case 174 /* ObjectBindingPattern */:
                    case 251 /* JsxOpeningElement */:
                    case 250 /* JsxSelfClosingElement */:
                    case 256 /* JsxExpression */:
                    case 150 /* MethodSignature */:
                    case 155 /* CallSignature */:
                    case 156 /* ConstructSignature */:
                    case 146 /* Parameter */:
                    case 160 /* FunctionType */:
                    case 161 /* ConstructorType */:
                    case 168 /* ParenthesizedType */:
                    case 183 /* TaggedTemplateExpression */:
                    case 191 /* AwaitExpression */:
                    case 245 /* NamedExports */:
                    case 241 /* NamedImports */:
                    case 246 /* ExportSpecifier */:
                    case 242 /* ImportSpecifier */:
                    case 261 /* PropertyAssignment */:
                    case 149 /* PropertyDeclaration */:
                        return true;
                }
                return false;
            }
            /* @internal */
            function nodeWillIndentChild(parent, child, indentByDefault) {
                var childKind = child ? child.kind : 0 /* Unknown */;
                switch (parent.kind) {
                    case 212 /* DoStatement */:
                    case 213 /* WhileStatement */:
                    case 215 /* ForInStatement */:
                    case 216 /* ForOfStatement */:
                    case 214 /* ForStatement */:
                    case 211 /* IfStatement */:
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                    case 151 /* MethodDeclaration */:
                    case 187 /* ArrowFunction */:
                    case 152 /* Constructor */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                        return childKind !== 207 /* Block */;
                    case 244 /* ExportDeclaration */:
                        return childKind !== 245 /* NamedExports */;
                    case 238 /* ImportDeclaration */:
                        return childKind !== 239 /* ImportClause */ ||
                            (child.namedBindings && child.namedBindings.kind !== 241 /* NamedImports */);
                    case 249 /* JsxElement */:
                        return childKind !== 252 /* JsxClosingElement */;
                }
                // No explicit rule for given nodes so the result will follow the default value argument
                return indentByDefault;
            }
            SmartIndenter.nodeWillIndentChild = nodeWillIndentChild;
            /*
            Function returns true when the parent node should indent the given child by an explicit rule
            */
            function shouldIndentChildNode(parent, child) {
                return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false);
            }
            SmartIndenter.shouldIndentChildNode = shouldIndentChildNode;
        })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var textChanges;
    (function (textChanges) {
        /**
         * Currently for simplicity we store recovered positions on the node itself.
         * It can be changed to side-table later if we decide that current design is too invasive.
         */
        function getPos(n) {
            var result = n.__pos;
            ts.Debug.assert(typeof result === "number");
            return result;
        }
        function setPos(n, pos) {
            ts.Debug.assert(typeof pos === "number");
            n.__pos = pos;
        }
        function getEnd(n) {
            var result = n.__end;
            ts.Debug.assert(typeof result === "number");
            return result;
        }
        function setEnd(n, end) {
            ts.Debug.assert(typeof end === "number");
            n.__end = end;
        }
        var Position;
        (function (Position) {
            Position[Position["FullStart"] = 0] = "FullStart";
            Position[Position["Start"] = 1] = "Start";
        })(Position = textChanges.Position || (textChanges.Position = {}));
        function skipWhitespacesAndLineBreaks(text, start) {
            return ts.skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        function hasCommentsBeforeLineBreak(text, start) {
            var i = start;
            while (i < text.length) {
                var ch = text.charCodeAt(i);
                if (ts.isWhiteSpaceSingleLine(ch)) {
                    i++;
                    continue;
                }
                return ch === 47 /* slash */;
            }
            return false;
        }
        var ChangeKind;
        (function (ChangeKind) {
            ChangeKind[ChangeKind["Remove"] = 0] = "Remove";
            ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode";
            ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes";
        })(ChangeKind || (ChangeKind = {}));
        function getSeparatorCharacter(separator) {
            return ts.tokenToString(separator.kind);
        }
        textChanges.getSeparatorCharacter = getSeparatorCharacter;
        function getAdjustedStartPosition(sourceFile, node, options, position) {
            if (options.useNonAdjustedStartPosition) {
                return node.getFullStart();
            }
            var fullStart = node.getFullStart();
            var start = node.getStart(sourceFile);
            if (fullStart === start) {
                return start;
            }
            var fullStartLine = ts.getLineStartPositionForPosition(fullStart, sourceFile);
            var startLine = ts.getLineStartPositionForPosition(start, sourceFile);
            if (startLine === fullStartLine) {
                // full start and start of the node are on the same line
                //   a,     b;
                //    ^     ^
                //    |   start
                // fullstart
                // when b is replaced - we usually want to keep the leading trvia
                // when b is deleted - we delete it
                return position === Position.Start ? start : fullStart;
            }
            // get start position of the line following the line that contains fullstart position
            // (but only if the fullstart isn't the very beginning of the file)
            var nextLineStart = fullStart > 0 ? 1 : 0;
            var adjustedStartPosition = ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile);
            // skip whitespaces/newlines
            adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition);
            return ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile);
        }
        textChanges.getAdjustedStartPosition = getAdjustedStartPosition;
        function getAdjustedEndPosition(sourceFile, node, options) {
            if (options.useNonAdjustedEndPosition || ts.isExpression(node)) {
                return node.getEnd();
            }
            var end = node.getEnd();
            var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true);
            return newEnd !== end && ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1))
                ? newEnd
                : end;
        }
        textChanges.getAdjustedEndPosition = getAdjustedEndPosition;
        /**
         * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element
         */
        function isSeparator(node, candidate) {
            return candidate && node.parent && (candidate.kind === 26 /* CommaToken */ || (candidate.kind === 25 /* SemicolonToken */ && node.parent.kind === 178 /* ObjectLiteralExpression */));
        }
        function spaces(count) {
            var s = "";
            for (var i = 0; i < count; i++) {
                s += " ";
            }
            return s;
        }
        var ChangeTracker = /** @class */ (function () {
            function ChangeTracker(newLine, rulesProvider, validator) {
                this.newLine = newLine;
                this.rulesProvider = rulesProvider;
                this.validator = validator;
                this.changes = [];
                this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine });
            }
            ChangeTracker.fromContext = function (context) {
                return new ChangeTracker(context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */, context.rulesProvider);
            };
            ChangeTracker.with = function (context, cb) {
                var tracker = ChangeTracker.fromContext(context);
                cb(tracker);
                return tracker.getChanges();
            };
            ChangeTracker.prototype.deleteRange = function (sourceFile, range) {
                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range });
                return this;
            };
            ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) {
                if (options === void 0) { options = {}; }
                var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart);
                var endPosition = getAdjustedEndPosition(sourceFile, node, options);
                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } });
                return this;
            };
            ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) {
                if (options === void 0) { options = {}; }
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart);
                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } });
                return this;
            };
            ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) {
                var containingList = ts.formatting.SmartIndenter.getContainingList(node, sourceFile);
                if (!containingList) {
                    ts.Debug.fail("node is not a list element");
                    return this;
                }
                var index = ts.indexOfNode(containingList, node);
                if (index < 0) {
                    return this;
                }
                if (containingList.length === 1) {
                    this.deleteNode(sourceFile, node);
                    return this;
                }
                if (index !== containingList.length - 1) {
                    var nextToken = ts.getTokenAtPosition(sourceFile, node.end, /*includeJsDocComment*/ false);
                    if (nextToken && isSeparator(node, nextToken)) {
                        // find first non-whitespace position in the leading trivia of the node
                        var startPosition = ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
                        var nextElement = containingList[index + 1];
                        /// find first non-whitespace position in the leading trivia of the next node
                        var endPosition = ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
                        // shift next node so its first non-whitespace position will be moved to the first non-whitespace position of the deleted node
                        this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
                    }
                }
                else {
                    var previousToken = ts.getTokenAtPosition(sourceFile, containingList[index - 1].end, /*includeJsDocComment*/ false);
                    if (previousToken && isSeparator(node, previousToken)) {
                        this.deleteNodeRange(sourceFile, previousToken, node);
                    }
                }
                return this;
            };
            ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) {
                if (options === void 0) { options = {}; }
                this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode });
                return this;
            };
            ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) {
                if (options === void 0) { options = {}; }
                var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start);
                var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options);
                return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options);
            };
            ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) {
                if (options === void 0) { options = {}; }
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start);
                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
                return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options);
            };
            ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) {
                this.changes.push({
                    kind: ChangeKind.ReplaceWithSingleNode,
                    sourceFile: sourceFile,
                    options: options,
                    node: newNode,
                    range: { pos: startPosition, end: endPosition }
                });
                return this;
            };
            ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) {
                this.changes.push({
                    kind: ChangeKind.ReplaceWithMultipleNodes,
                    sourceFile: sourceFile,
                    options: options,
                    nodes: newNodes,
                    range: { pos: startPosition, end: endPosition }
                });
                return this;
            };
            ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) {
                var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start);
                var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options);
                return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options);
            };
            ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) {
                var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start);
                var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options);
                return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options);
            };
            ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) {
                return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options);
            };
            ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) {
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start);
                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
                return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options);
            };
            ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) {
                if (options === void 0) { options = {}; }
                this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } });
                return this;
            };
            ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) {
                if (options === void 0) { options = {}; }
                var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start);
                return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options);
            };
            ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) {
                if (options === void 0) { options = {}; }
                if ((ts.isStatementButNotDeclaration(after)) ||
                    after.kind === 149 /* PropertyDeclaration */ ||
                    after.kind === 148 /* PropertySignature */ ||
                    after.kind === 150 /* MethodSignature */) {
                    // check if previous statement ends with semicolon
                    // if not - insert semicolon to preserve the code from changing the meaning due to ASI
                    if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) {
                        this.changes.push({
                            kind: ChangeKind.ReplaceWithSingleNode,
                            sourceFile: sourceFile,
                            options: {},
                            range: { pos: after.end, end: after.end },
                            node: ts.createToken(25 /* SemicolonToken */)
                        });
                    }
                }
                var endPosition = getAdjustedEndPosition(sourceFile, after, options);
                return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options);
            };
            /**
             * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
             * i.e. arguments in arguments lists, parameters in parameter lists etc.
             * Note that separators are part of the node in statements and class elements.
             */
            ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode) {
                var containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile);
                if (!containingList) {
                    ts.Debug.fail("node is not a list element");
                    return this;
                }
                var index = ts.indexOfNode(containingList, after);
                if (index < 0) {
                    return this;
                }
                var end = after.getEnd();
                if (index !== containingList.length - 1) {
                    // any element except the last one
                    // use next sibling as an anchor
                    var nextToken = ts.getTokenAtPosition(sourceFile, after.end, /*includeJsDocComment*/ false);
                    if (nextToken && isSeparator(after, nextToken)) {
                        // for list
                        // a, b, c
                        // create change for adding 'e' after 'a' as
                        // - find start of next element after a (it is b)
                        // - use this start as start and end position in final change
                        // - build text of change by formatting the text of node + separator + whitespace trivia of b
                        // in multiline case it will work as
                        //   a,
                        //   b,
                        //   c,
                        // result - '*' denotes leading trivia that will be inserted after new text (displayed as '#')
                        //   a,*
                        // ***insertedtext<separator>#
                        // ###b,
                        //   c,
                        // find line and character of the next element
                        var lineAndCharOfNextElement = ts.getLineAndCharacterOfPosition(sourceFile, skipWhitespacesAndLineBreaks(sourceFile.text, containingList[index + 1].getFullStart()));
                        // find line and character of the token that precedes next element (usually it is separator)
                        var lineAndCharOfNextToken = ts.getLineAndCharacterOfPosition(sourceFile, nextToken.end);
                        var prefix = void 0;
                        var startPos = void 0;
                        if (lineAndCharOfNextToken.line === lineAndCharOfNextElement.line) {
                            // next element is located on the same line with separator:
                            // a,$$$$b
                            //  ^    ^
                            //  |    |-next element
                            //  |-separator
                            // where $$$ is some leading trivia
                            // for a newly inserted node we'll maintain the same relative position comparing to separator and replace leading trivia with spaces
                            // a,    x,$$$$b
                            //  ^    ^     ^
                            //  |    |     |-next element
                            //  |    |-new inserted node padded with spaces
                            //  |-separator
                            startPos = nextToken.end;
                            prefix = spaces(lineAndCharOfNextElement.character - lineAndCharOfNextToken.character);
                        }
                        else {
                            // next element is located on different line that separator
                            // let insert position be the beginning of the line that contains next element
                            startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile);
                        }
                        this.changes.push({
                            kind: ChangeKind.ReplaceWithSingleNode,
                            sourceFile: sourceFile,
                            range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) },
                            node: newNode,
                            options: {
                                prefix: prefix,
                                // write separator and leading trivia of the next element as suffix
                                suffix: "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile))
                            }
                        });
                    }
                }
                else {
                    var afterStart = after.getStart(sourceFile);
                    var afterStartLinePosition = ts.getLineStartPositionForPosition(afterStart, sourceFile);
                    var separator = void 0;
                    var multilineList = false;
                    // insert element after the last element in the list that has more than one item
                    // pick the element preceding the after element to:
                    // - pick the separator
                    // - determine if list is a multiline
                    if (containingList.length === 1) {
                        // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise
                        // i.e. var x = 1 // this is x
                        //     | new element will be inserted at this position
                        separator = 26 /* CommaToken */;
                    }
                    else {
                        // element has more than one element, pick separator from the list
                        var tokenBeforeInsertPosition = ts.findPrecedingToken(after.pos, sourceFile);
                        separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : 26 /* CommaToken */;
                        // determine if list is multiline by checking lines of after element and element that precedes it.
                        var afterMinusOneStartLinePosition = ts.getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile);
                        multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition;
                    }
                    if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) {
                        // in this case we'll always treat containing list as multiline
                        multilineList = true;
                    }
                    if (multilineList) {
                        // insert separator immediately following the 'after' node to preserve comments in trailing trivia
                        this.changes.push({
                            kind: ChangeKind.ReplaceWithSingleNode,
                            sourceFile: sourceFile,
                            range: { pos: end, end: end },
                            node: ts.createToken(separator),
                            options: {}
                        });
                        // use the same indentation as 'after' item
                        var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.rulesProvider.getFormatOptions());
                        // insert element before the line break on the line that contains 'after' element
                        var insertPos = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false);
                        if (insertPos !== end && ts.isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) {
                            insertPos--;
                        }
                        this.changes.push({
                            kind: ChangeKind.ReplaceWithSingleNode,
                            sourceFile: sourceFile,
                            range: { pos: insertPos, end: insertPos },
                            node: newNode,
                            options: { indentation: indentation, prefix: this.newLineCharacter }
                        });
                    }
                    else {
                        this.changes.push({
                            kind: ChangeKind.ReplaceWithSingleNode,
                            sourceFile: sourceFile,
                            range: { pos: end, end: end },
                            node: newNode,
                            options: { prefix: ts.tokenToString(separator) + " " }
                        });
                    }
                }
                return this;
            };
            ChangeTracker.prototype.getChanges = function () {
                var _this = this;
                var changesPerFile = ts.createMap();
                // group changes per file
                for (var _i = 0, _a = this.changes; _i < _a.length; _i++) {
                    var c = _a[_i];
                    var changesInFile = changesPerFile.get(c.sourceFile.path);
                    if (!changesInFile) {
                        changesPerFile.set(c.sourceFile.path, changesInFile = []);
                    }
                    changesInFile.push(c);
                }
                // convert changes
                var fileChangesList = [];
                changesPerFile.forEach(function (changesInFile) {
                    var sourceFile = changesInFile[0].sourceFile;
                    var fileTextChanges = { fileName: sourceFile.fileName, textChanges: [] };
                    for (var _i = 0, _a = ChangeTracker.normalize(changesInFile); _i < _a.length; _i++) {
                        var c = _a[_i];
                        fileTextChanges.textChanges.push({
                            span: _this.computeSpan(c, sourceFile),
                            newText: _this.computeNewText(c, sourceFile)
                        });
                    }
                    fileChangesList.push(fileTextChanges);
                });
                return fileChangesList;
            };
            ChangeTracker.prototype.computeSpan = function (change, _sourceFile) {
                return ts.createTextSpanFromBounds(change.range.pos, change.range.end);
            };
            ChangeTracker.prototype.computeNewText = function (change, sourceFile) {
                var _this = this;
                if (change.kind === ChangeKind.Remove) {
                    // deletion case
                    return "";
                }
                var options = change.options || {};
                var text;
                var pos = change.range.pos;
                var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos;
                if (change.kind === ChangeKind.ReplaceWithMultipleNodes) {
                    var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); });
                    text = parts.join(change.options.nodeSeparator);
                }
                else {
                    ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode");
                    text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options);
                }
                // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line
                text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, "");
                return (options.prefix || "") + text + (options.suffix || "");
            };
            ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) {
                var nonformattedText = getNonformattedText(node, sourceFile, this.newLine);
                if (this.validator) {
                    this.validator(nonformattedText);
                }
                var formatOptions = this.rulesProvider.getFormatOptions();
                var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos;
                var initialIndentation = options.indentation !== undefined
                    ? options.indentation
                    : (options.useIndentationFromFile !== false)
                        ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter))
                        : 0;
                var delta = options.delta !== undefined
                    ? options.delta
                    : ts.formatting.SmartIndenter.shouldIndentChildNode(node)
                        ? (formatOptions.indentSize || 0)
                        : 0;
                return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider);
            };
            ChangeTracker.normalize = function (changes) {
                // order changes by start position
                var normalized = ts.stableSort(changes, function (a, b) { return a.range.pos - b.range.pos; });
                // verify that change intervals do not overlap, except possibly at end points.
                for (var i = 0; i < normalized.length - 2; i++) {
                    ts.Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos);
                }
                return normalized;
            };
            return ChangeTracker;
        }());
        textChanges.ChangeTracker = ChangeTracker;
        function getNonformattedText(node, sourceFile, newLine) {
            var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion };
            var writer = new Writer(ts.getNewLineCharacter(options));
            var printer = ts.createPrinter(options, writer);
            printer.writeNode(4 /* Unspecified */, node, sourceFile, writer);
            return { text: writer.getText(), node: assignPositionsToNode(node) };
        }
        function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, rulesProvider) {
            var lineMap = ts.computeLineStarts(nonFormattedText.text);
            var file = {
                text: nonFormattedText.text,
                lineMap: lineMap,
                getLineAndCharacterOfPosition: function (pos) { return ts.computeLineAndCharacterOfPosition(lineMap, pos); }
            };
            var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider);
            return applyChanges(nonFormattedText.text, changes);
        }
        function applyChanges(text, changes) {
            for (var i = changes.length - 1; i >= 0; i--) {
                var change = changes[i];
                text = "" + text.substring(0, change.span.start) + change.newText + text.substring(ts.textSpanEnd(change.span));
            }
            return text;
        }
        textChanges.applyChanges = applyChanges;
        function isTrivia(s) {
            return ts.skipTrivia(s, 0) === s.length;
        }
        function assignPositionsToNode(node) {
            var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode);
            // create proxy node for non synthesized nodes
            var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited);
            newNode.pos = getPos(node);
            newNode.end = getEnd(node);
            return newNode;
        }
        function assignPositionsToNodeArray(nodes, visitor, test, start, count) {
            var visited = ts.visitNodes(nodes, visitor, test, start, count);
            if (!visited) {
                return visited;
            }
            // clone nodearray if necessary
            var nodeArray = visited === nodes ? ts.createNodeArray(visited.slice(0)) : visited;
            nodeArray.pos = getPos(nodes);
            nodeArray.end = getEnd(nodes);
            return nodeArray;
        }
        var Writer = /** @class */ (function () {
            function Writer(newLine) {
                var _this = this;
                this.lastNonTriviaPosition = 0;
                this.writer = ts.createTextWriter(newLine);
                this.onEmitNode = function (hint, node, printCallback) {
                    if (node) {
                        setPos(node, _this.lastNonTriviaPosition);
                    }
                    printCallback(hint, node);
                    if (node) {
                        setEnd(node, _this.lastNonTriviaPosition);
                    }
                };
                this.onBeforeEmitNodeArray = function (nodes) {
                    if (nodes) {
                        setPos(nodes, _this.lastNonTriviaPosition);
                    }
                };
                this.onAfterEmitNodeArray = function (nodes) {
                    if (nodes) {
                        setEnd(nodes, _this.lastNonTriviaPosition);
                    }
                };
                this.onBeforeEmitToken = function (node) {
                    if (node) {
                        setPos(node, _this.lastNonTriviaPosition);
                    }
                };
                this.onAfterEmitToken = function (node) {
                    if (node) {
                        setEnd(node, _this.lastNonTriviaPosition);
                    }
                };
            }
            Writer.prototype.setLastNonTriviaPosition = function (s, force) {
                if (force || !isTrivia(s)) {
                    this.lastNonTriviaPosition = this.writer.getTextPos();
                    var i = 0;
                    while (ts.isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) {
                        i++;
                    }
                    // trim trailing whitespaces
                    this.lastNonTriviaPosition -= i;
                }
            };
            Writer.prototype.write = function (s) {
                this.writer.write(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeTextOfNode = function (text, node) {
                this.writer.writeTextOfNode(text, node);
            };
            Writer.prototype.writeLine = function () {
                this.writer.writeLine();
            };
            Writer.prototype.increaseIndent = function () {
                this.writer.increaseIndent();
            };
            Writer.prototype.decreaseIndent = function () {
                this.writer.decreaseIndent();
            };
            Writer.prototype.getText = function () {
                return this.writer.getText();
            };
            Writer.prototype.rawWrite = function (s) {
                this.writer.rawWrite(s);
                this.setLastNonTriviaPosition(s, /*force*/ false);
            };
            Writer.prototype.writeLiteral = function (s) {
                this.writer.writeLiteral(s);
                this.setLastNonTriviaPosition(s, /*force*/ true);
            };
            Writer.prototype.getTextPos = function () {
                return this.writer.getTextPos();
            };
            Writer.prototype.getLine = function () {
                return this.writer.getLine();
            };
            Writer.prototype.getColumn = function () {
                return this.writer.getColumn();
            };
            Writer.prototype.getIndent = function () {
                return this.writer.getIndent();
            };
            Writer.prototype.isAtStartOfLine = function () {
                return this.writer.isAtStartOfLine();
            };
            Writer.prototype.reset = function () {
                this.writer.reset();
                this.lastNonTriviaPosition = 0;
            };
            return Writer;
        }());
    })(textChanges = ts.textChanges || (ts.textChanges = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var codeFixes = [];
        function registerCodeFix(codeFix) {
            ts.forEach(codeFix.errorCodes, function (error) {
                var fixes = codeFixes[error];
                if (!fixes) {
                    fixes = [];
                    codeFixes[error] = fixes;
                }
                fixes.push(codeFix);
            });
        }
        codefix.registerCodeFix = registerCodeFix;
        function getSupportedErrorCodes() {
            return Object.keys(codeFixes);
        }
        codefix.getSupportedErrorCodes = getSupportedErrorCodes;
        function getFixes(context) {
            var fixes = codeFixes[context.errorCode];
            var allActions = [];
            ts.forEach(fixes, function (f) {
                var actions = f.getCodeActions(context);
                if (actions && actions.length > 0) {
                    for (var _i = 0, actions_1 = actions; _i < actions_1.length; _i++) {
                        var action = actions_1[_i];
                        if (action === undefined) {
                            context.host.log("Action for error code " + context.errorCode + " added an invalid action entry; please log a bug");
                        }
                        else {
                            allActions.push(action);
                        }
                    }
                }
            });
            return allActions;
        }
        codefix.getFixes = getFixes;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor_1) {
        // A map with the refactor code as key, the refactor itself as value
        // e.g.  nonSuggestableRefactors[refactorCode] -> the refactor you want
        var refactors = ts.createMap();
        function registerRefactor(refactor) {
            refactors.set(refactor.name, refactor);
        }
        refactor_1.registerRefactor = registerRefactor;
        function getApplicableRefactors(context) {
            return ts.flatMapIter(refactors.values(), function (refactor) {
                return context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context);
            });
        }
        refactor_1.getApplicableRefactors = getApplicableRefactors;
        function getEditsForRefactor(context, refactorName, actionName) {
            var refactor = refactors.get(refactorName);
            return refactor && refactor.getEditsForAction(context, actionName);
        }
        refactor_1.getEditsForRefactor = getEditsForRefactor;
    })(refactor = ts.refactor || (ts.refactor = {}));
    function getRefactorContextLength(context) {
        return context.endPosition === undefined ? 0 : context.endPosition - context.startPosition;
    }
    ts.getRefactorContextLength = getRefactorContextLength;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
                var decorator = ts.getAncestor(token, 147 /* Decorator */);
                ts.Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
                var replacement = ts.createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
                return [{
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Call_decorator_expression),
                        changes: changeTracker.getChanges()
                    }];
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
                var qualifiedName = ts.getAncestor(token, 143 /* QualifiedName */);
                ts.Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
                if (!ts.isIdentifier(qualifiedName.left)) {
                    return undefined;
                }
                var leftText = qualifiedName.left.getText(sourceFile);
                var rightText = qualifiedName.right.getText(sourceFile);
                var replacement = ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), ts.createLiteralTypeNode(ts.createLiteral(rightText)));
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
                return [{
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Rewrite_as_the_indexed_access_type_0), [leftText + "[\"" + rightText + "\"]"]),
                        changes: changeTracker.getChanges()
                    }];
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code],
            getCodeActions: getActionForClassLikeIncorrectImplementsInterface
        });
        function getActionForClassLikeIncorrectImplementsInterface(context) {
            var sourceFile = context.sourceFile;
            var start = context.span.start;
            var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
            var checker = context.program.getTypeChecker();
            var classDeclaration = ts.getContainingClass(token);
            if (!classDeclaration) {
                return undefined;
            }
            var openBrace = ts.getOpenBraceOfClassLike(classDeclaration, sourceFile);
            var classType = checker.getTypeAtLocation(classDeclaration);
            var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(classDeclaration);
            var hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, 1 /* Number */);
            var hasStringIndexSignature = !!checker.getIndexTypeOfType(classType, 0 /* String */);
            var result = [];
            for (var _i = 0, implementedTypeNodes_2 = implementedTypeNodes; _i < implementedTypeNodes_2.length; _i++) {
                var implementedTypeNode = implementedTypeNodes_2[_i];
                // Note that this is ultimately derived from a map indexed by symbol names,
                // so duplicates cannot occur.
                var implementedType = checker.getTypeAtLocation(implementedTypeNode);
                var implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
                var nonPrivateMembers = implementedTypeSymbols.filter(function (symbol) { return !(ts.getModifierFlags(symbol.valueDeclaration) & 8 /* Private */); });
                var newNodes = [];
                createAndAddMissingIndexSignatureDeclaration(implementedType, 1 /* Number */, hasNumericIndexSignature, newNodes);
                createAndAddMissingIndexSignatureDeclaration(implementedType, 0 /* String */, hasStringIndexSignature, newNodes);
                newNodes = newNodes.concat(codefix.createMissingMemberNodes(classDeclaration, nonPrivateMembers, checker));
                var message = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]);
                if (newNodes.length > 0) {
                    pushAction(result, newNodes, message);
                }
            }
            return result;
            function createAndAddMissingIndexSignatureDeclaration(type, kind, hasIndexSigOfKind, newNodes) {
                if (hasIndexSigOfKind) {
                    return;
                }
                var indexInfoOfKind = checker.getIndexInfoOfType(type, kind);
                if (!indexInfoOfKind) {
                    return;
                }
                var newIndexSignatureDeclaration = checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration);
                newNodes.push(newIndexSignatureDeclaration);
            }
            function pushAction(result, newNodes, description) {
                result.push({ description: description, changes: codefix.newNodesToChanges(newNodes, openBrace, context) });
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Property_0_does_not_exist_on_type_1.code,
                ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code],
            getCodeActions: getActionsForAddMissingMember
        });
        function getActionsForAddMissingMember(context) {
            var tokenSourceFile = context.sourceFile;
            var start = context.span.start;
            // The identifier of the missing property. eg:
            // this.missing = 1;
            //      ^^^^^^^
            var token = ts.getTokenAtPosition(tokenSourceFile, start, /*includeJsDocComment*/ false);
            if (token.kind !== 71 /* Identifier */) {
                return undefined;
            }
            if (!ts.isPropertyAccessExpression(token.parent)) {
                return undefined;
            }
            var tokenName = token.getText(tokenSourceFile);
            var makeStatic = false;
            var classDeclaration;
            if (token.parent.expression.kind === 99 /* ThisKeyword */) {
                var containingClassMemberDeclaration = ts.getThisContainer(token, /*includeArrowFunctions*/ false);
                if (!ts.isClassElement(containingClassMemberDeclaration)) {
                    return undefined;
                }
                classDeclaration = containingClassMemberDeclaration.parent;
                // Property accesses on `this` in a static method are accesses of a static member.
                makeStatic = classDeclaration && ts.hasModifier(containingClassMemberDeclaration, 32 /* Static */);
            }
            else {
                var checker = context.program.getTypeChecker();
                var leftExpression = token.parent.expression;
                var leftExpressionType = checker.getTypeAtLocation(leftExpression);
                if (leftExpressionType.flags & 32768 /* Object */) {
                    var symbol = leftExpressionType.symbol;
                    if (symbol.flags & 32 /* Class */) {
                        classDeclaration = symbol.declarations && symbol.declarations[0];
                        if (leftExpressionType !== checker.getDeclaredTypeOfSymbol(symbol)) {
                            // The expression is a class symbol but the type is not the instance-side.
                            makeStatic = true;
                        }
                    }
                }
            }
            if (!classDeclaration || !ts.isClassLike(classDeclaration)) {
                return undefined;
            }
            var classDeclarationSourceFile = ts.getSourceFileOfNode(classDeclaration);
            var classOpenBrace = ts.getOpenBraceOfClassLike(classDeclaration, classDeclarationSourceFile);
            return ts.isInJavaScriptFile(classDeclarationSourceFile) ?
                getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) :
                getActionsForAddMissingMemberInTypeScriptFile(classDeclaration, makeStatic);
            function getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) {
                var actions;
                var methodCodeAction = getActionForMethodDeclaration(/*includeTypeScriptSyntax*/ false);
                if (methodCodeAction) {
                    actions = [methodCodeAction];
                }
                if (makeStatic) {
                    if (classDeclaration.kind === 199 /* ClassExpression */) {
                        return actions;
                    }
                    var className = classDeclaration.name.getText();
                    var staticInitialization = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier(className), tokenName), ts.createIdentifier("undefined")));
                    var staticInitializationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                    staticInitializationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classDeclaration, staticInitialization, { prefix: context.newLineCharacter, suffix: context.newLineCharacter });
                    var initializeStaticAction = {
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Initialize_static_property_0), [tokenName]),
                        changes: staticInitializationChangeTracker.getChanges()
                    };
                    (actions || (actions = [])).push(initializeStaticAction);
                    return actions;
                }
                else {
                    var classConstructor = ts.getFirstConstructorWithBody(classDeclaration);
                    if (!classConstructor) {
                        return actions;
                    }
                    var propertyInitialization = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createThis(), tokenName), ts.createIdentifier("undefined")));
                    var propertyInitializationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                    propertyInitializationChangeTracker.insertNodeBefore(classDeclarationSourceFile, classConstructor.body.getLastToken(), propertyInitialization, { suffix: context.newLineCharacter });
                    var initializeAction = {
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Initialize_property_0_in_the_constructor), [tokenName]),
                        changes: propertyInitializationChangeTracker.getChanges()
                    };
                    (actions || (actions = [])).push(initializeAction);
                    return actions;
                }
            }
            function getActionsForAddMissingMemberInTypeScriptFile(classDeclaration, makeStatic) {
                var actions;
                var methodCodeAction = getActionForMethodDeclaration(/*includeTypeScriptSyntax*/ true);
                if (methodCodeAction) {
                    actions = [methodCodeAction];
                }
                var typeNode;
                if (token.parent.parent.kind === 194 /* BinaryExpression */) {
                    var binaryExpression = token.parent.parent;
                    var otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left;
                    var checker = context.program.getTypeChecker();
                    var widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)));
                    typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
                }
                typeNode = typeNode || ts.createKeywordTypeNode(119 /* AnyKeyword */);
                var property = ts.createProperty(
                /*decorators*/ undefined, 
                /*modifiers*/ makeStatic ? [ts.createToken(115 /* StaticKeyword */)] : undefined, tokenName, 
                /*questionToken*/ undefined, typeNode, 
                /*initializer*/ undefined);
                var propertyChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                propertyChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, property, { suffix: context.newLineCharacter });
                var diag = makeStatic ? ts.Diagnostics.Declare_static_property_0 : ts.Diagnostics.Declare_property_0;
                actions = ts.append(actions, {
                    description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag), [tokenName]),
                    changes: propertyChangeTracker.getChanges()
                });
                if (!makeStatic) {
                    // Index signatures cannot have the static modifier.
                    var stringTypeNode = ts.createKeywordTypeNode(136 /* StringKeyword */);
                    var indexingParameter = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, "x", 
                    /*questionToken*/ undefined, stringTypeNode, 
                    /*initializer*/ undefined);
                    var indexSignature = ts.createIndexSignature(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, [indexingParameter], typeNode);
                    var indexSignatureChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                    indexSignatureChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, indexSignature, { suffix: context.newLineCharacter });
                    actions.push({
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Add_index_signature_for_property_0), [tokenName]),
                        changes: indexSignatureChangeTracker.getChanges()
                    });
                }
                return actions;
            }
            function getActionForMethodDeclaration(includeTypeScriptSyntax) {
                if (token.parent.parent.kind === 181 /* CallExpression */) {
                    var callExpression = token.parent.parent;
                    var methodDeclaration = codefix.createMethodFromCallExpression(callExpression, tokenName, includeTypeScriptSyntax, makeStatic);
                    var methodDeclarationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                    methodDeclarationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, methodDeclaration, { suffix: context.newLineCharacter });
                    var diag = makeStatic ? ts.Diagnostics.Declare_static_method_0 : ts.Diagnostics.Declare_method_0;
                    return {
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag), [tokenName]),
                        changes: methodDeclarationChangeTracker.getChanges()
                    };
                }
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
                ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code],
            getCodeActions: getActionsForCorrectSpelling
        });
        function getActionsForCorrectSpelling(context) {
            var sourceFile = context.sourceFile;
            // This is the identifier of the misspelled word. eg:
            // this.speling = 1;
            //      ^^^^^^^
            var node = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); // TODO: GH#15852
            var checker = context.program.getTypeChecker();
            var suggestion;
            if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
                ts.Debug.assert(node.kind === 71 /* Identifier */);
                var containingType = checker.getTypeAtLocation(node.parent.expression);
                suggestion = checker.getSuggestionForNonexistentProperty(node, containingType);
            }
            else {
                var meaning = ts.getMeaningFromLocation(node);
                suggestion = checker.getSuggestionForNonexistentSymbol(node, ts.getTextOfNode(node), convertSemanticMeaningToSymbolFlags(meaning));
            }
            if (suggestion) {
                return [{
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Change_spelling_to_0), [suggestion]),
                        changes: [{
                                fileName: sourceFile.fileName,
                                textChanges: [{
                                        span: { start: node.getStart(), length: node.getWidth() },
                                        newText: suggestion
                                    }],
                            }],
                    }];
            }
        }
        function convertSemanticMeaningToSymbolFlags(meaning) {
            var flags = 0;
            if (meaning & 4 /* Namespace */) {
                flags |= 1920 /* Namespace */;
            }
            if (meaning & 2 /* Type */) {
                flags |= 793064 /* Type */;
            }
            if (meaning & 1 /* Value */) {
                flags |= 107455 /* Value */;
            }
            return flags;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [
                ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
            ],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, start = context.span.start;
                var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
                if (!ts.isStringLiteral(token)) {
                    throw ts.Debug.fail(); // These errors should only happen on the module name.
                }
                var action = tryGetCodeActionForInstallPackageTypes(context.host, token.text);
                return action && [action];
            },
        });
        function tryGetCodeActionForInstallPackageTypes(host, moduleName) {
            var packageName = ts.getPackageName(moduleName).packageName;
            if (!host.isKnownTypesPackageName(packageName)) {
                // If !registry, registry not available yet, can't do anything.
                return undefined;
            }
            var typesPackageName = ts.getTypesPackageName(packageName);
            return {
                description: "Install '" + typesPackageName + "'",
                changes: [],
                commands: [{ type: "install package", packageName: typesPackageName }],
            };
        }
        codefix.tryGetCodeActionForInstallPackageTypes = tryGetCodeActionForInstallPackageTypes;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code],
            getCodeActions: getActionForClassLikeMissingAbstractMember
        });
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code],
            getCodeActions: getActionForClassLikeMissingAbstractMember
        });
        function getActionForClassLikeMissingAbstractMember(context) {
            var sourceFile = context.sourceFile;
            var start = context.span.start;
            // This is the identifier in the case of a class declaration
            // or the class keyword token in the case of a class expression.
            var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
            var checker = context.program.getTypeChecker();
            if (ts.isClassLike(token.parent)) {
                var classDeclaration = token.parent;
                var extendsNode = ts.getClassExtendsHeritageClauseElement(classDeclaration);
                var instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
                // Note that this is ultimately derived from a map indexed by symbol names,
                // so duplicates cannot occur.
                var extendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType);
                var abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember);
                var newNodes = codefix.createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, checker);
                var changes = codefix.newNodesToChanges(newNodes, ts.getOpenBraceOfClassLike(classDeclaration, sourceFile), context);
                if (changes && changes.length > 0) {
                    return [{
                            description: ts.getLocaleSpecificMessage(ts.Diagnostics.Implement_inherited_abstract_class),
                            changes: changes
                        }];
                }
            }
            return undefined;
        }
        function symbolPointsToNonPrivateAndAbstractMember(symbol) {
            var decls = symbol.getDeclarations();
            ts.Debug.assert(!!(decls && decls.length > 0));
            var flags = ts.getModifierFlags(decls[0]);
            return !(flags & 8 /* Private */) && !!(flags & 128 /* Abstract */);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
                if (token.kind !== 99 /* ThisKeyword */) {
                    return undefined;
                }
                var constructor = ts.getContainingFunction(token);
                var superCall = findSuperCall(constructor.body);
                if (!superCall) {
                    return undefined;
                }
                // figure out if the `this` access is actually inside the supercall
                // i.e. super(this.a), since in that case we won't suggest a fix
                if (superCall.expression && superCall.expression.kind === 181 /* CallExpression */) {
                    var expressionArguments = superCall.expression.arguments;
                    for (var i = 0; i < expressionArguments.length; i++) {
                        if (expressionArguments[i].expression === token) {
                            return undefined;
                        }
                    }
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                changeTracker.insertNodeAfter(sourceFile, ts.getOpenBrace(constructor, sourceFile), superCall, { suffix: context.newLineCharacter });
                changeTracker.deleteNode(sourceFile, superCall);
                return [{
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Make_super_call_the_first_statement_in_the_constructor),
                        changes: changeTracker.getChanges()
                    }];
                function findSuperCall(n) {
                    if (n.kind === 210 /* ExpressionStatement */ && ts.isSuperCall(n.expression)) {
                        return n;
                    }
                    if (ts.isFunctionLike(n)) {
                        return undefined;
                    }
                    return ts.forEachChild(n, findSuperCall);
                }
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
                if (token.kind !== 123 /* ConstructorKeyword */) {
                    return undefined;
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var superCall = ts.createStatement(ts.createCall(ts.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ ts.emptyArray));
                changeTracker.insertNodeAfter(sourceFile, ts.getOpenBrace(token.parent, sourceFile), superCall, { suffix: context.newLineCharacter });
                return [{
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Add_missing_super_call),
                        changes: changeTracker.getChanges()
                    }];
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var start = context.span.start;
                var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
                var classDeclNode = ts.getContainingClass(token);
                if (!(token.kind === 71 /* Identifier */ && ts.isClassLike(classDeclNode))) {
                    return undefined;
                }
                var heritageClauses = classDeclNode.heritageClauses;
                if (!(heritageClauses && heritageClauses.length > 0)) {
                    return undefined;
                }
                var extendsToken = heritageClauses[0].getFirstToken();
                if (!(extendsToken && extendsToken.kind === 85 /* ExtendsKeyword */)) {
                    return undefined;
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                changeTracker.replaceNode(sourceFile, extendsToken, ts.createToken(108 /* ImplementsKeyword */));
                // We replace existing keywords with commas.
                for (var i = 1; i < heritageClauses.length; i++) {
                    var keywordToken = heritageClauses[i].getFirstToken();
                    if (keywordToken) {
                        changeTracker.replaceNode(sourceFile, keywordToken, ts.createToken(26 /* CommaToken */));
                    }
                }
                var result = [{
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Change_extends_to_implements),
                        changes: changeTracker.getChanges()
                    }];
                return result;
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
                if (token.kind !== 71 /* Identifier */) {
                    return undefined;
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                changeTracker.replaceNode(sourceFile, token, ts.createPropertyAccess(ts.createThis(), token));
                return [{
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Add_this_to_unresolved_variable),
                        changes: changeTracker.getChanges()
                    }];
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [
                ts.Diagnostics._0_is_declared_but_its_value_is_never_read.code,
                ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code
            ],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var start = context.span.start;
                var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
                // this handles var ["computed"] = 12;
                if (token.kind === 21 /* OpenBracketToken */) {
                    token = ts.getTokenAtPosition(sourceFile, start + 1, /*includeJsDocComment*/ false);
                }
                switch (token.kind) {
                    case 71 /* Identifier */:
                        return deleteIdentifierOrPrefixWithUnderscore(token);
                    case 149 /* PropertyDeclaration */:
                    case 240 /* NamespaceImport */:
                        return [deleteNode(token.parent)];
                    default:
                        return deleteDefault();
                }
                function deleteDefault() {
                    if (ts.isDeclarationName(token)) {
                        return [deleteNode(token.parent)];
                    }
                    else if (ts.isLiteralComputedPropertyDeclarationName(token)) {
                        return [deleteNode(token.parent.parent)];
                    }
                    else {
                        return undefined;
                    }
                }
                function prefixIdentifierWithUnderscore(identifier) {
                    var startPosition = identifier.getStart(sourceFile, /*includeJsDocComment*/ false);
                    return {
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Prefix_0_with_an_underscore), { 0: token.getText() }),
                        changes: [{
                                fileName: sourceFile.path,
                                textChanges: [{
                                        span: { start: startPosition, length: 0 },
                                        newText: "_"
                                    }]
                            }]
                    };
                }
                function deleteIdentifierOrPrefixWithUnderscore(identifier) {
                    var parent = identifier.parent;
                    switch (parent.kind) {
                        case 226 /* VariableDeclaration */:
                            return deleteVariableDeclarationOrPrefixWithUnderscore(identifier, parent);
                        case 145 /* TypeParameter */:
                            var typeParameters = parent.parent.typeParameters;
                            if (typeParameters.length === 1) {
                                var previousToken = ts.getTokenAtPosition(sourceFile, typeParameters.pos - 1, /*includeJsDocComment*/ false);
                                var nextToken = ts.getTokenAtPosition(sourceFile, typeParameters.end, /*includeJsDocComment*/ false);
                                ts.Debug.assert(previousToken.kind === 27 /* LessThanToken */);
                                ts.Debug.assert(nextToken.kind === 29 /* GreaterThanToken */);
                                return [deleteNodeRange(previousToken, nextToken)];
                            }
                            else {
                                return [deleteNodeInList(parent)];
                            }
                        case 146 /* Parameter */:
                            var functionDeclaration = parent.parent;
                            return [functionDeclaration.parameters.length === 1 ? deleteNode(parent) : deleteNodeInList(parent),
                                prefixIdentifierWithUnderscore(identifier)];
                        // handle case where 'import a = A;'
                        case 237 /* ImportEqualsDeclaration */:
                            var importEquals = ts.getAncestor(identifier, 237 /* ImportEqualsDeclaration */);
                            return [deleteNode(importEquals)];
                        case 242 /* ImportSpecifier */:
                            var namedImports = parent.parent;
                            if (namedImports.elements.length === 1) {
                                return deleteNamedImportBinding(namedImports);
                            }
                            else {
                                // delete import specifier
                                return [deleteNodeInList(parent)];
                            }
                        case 239 /* ImportClause */:// this covers both 'import |d|' and 'import |d,| *'
                            var importClause = parent;
                            if (!importClause.namedBindings) {
                                var importDecl = ts.getAncestor(importClause, 238 /* ImportDeclaration */);
                                return [deleteNode(importDecl)];
                            }
                            else {
                                // import |d,| * as ns from './file'
                                var start_6 = importClause.name.getStart(sourceFile);
                                var nextToken = ts.getTokenAtPosition(sourceFile, importClause.name.end, /*includeJsDocComment*/ false);
                                if (nextToken && nextToken.kind === 26 /* CommaToken */) {
                                    // shift first non-whitespace position after comma to the start position of the node
                                    return [deleteRange({ pos: start_6, end: ts.skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) })];
                                }
                                else {
                                    return [deleteNode(importClause.name)];
                                }
                            }
                        case 240 /* NamespaceImport */:
                            return deleteNamedImportBinding(parent);
                        default:
                            return deleteDefault();
                    }
                }
                function deleteNamedImportBinding(namedBindings) {
                    if (namedBindings.parent.name) {
                        // Delete named imports while preserving the default import
                        // import d|, * as ns| from './file'
                        // import d|, { a }| from './file'
                        var previousToken = ts.getTokenAtPosition(sourceFile, namedBindings.pos - 1, /*includeJsDocComment*/ false);
                        if (previousToken && previousToken.kind === 26 /* CommaToken */) {
                            return [deleteRange({ pos: previousToken.getStart(), end: namedBindings.end })];
                        }
                        return undefined;
                    }
                    else {
                        // Delete the entire import declaration
                        // |import * as ns from './file'|
                        // |import { a } from './file'|
                        var importDecl = ts.getAncestor(namedBindings, 238 /* ImportDeclaration */);
                        return [deleteNode(importDecl)];
                    }
                }
                // token.parent is a variableDeclaration
                function deleteVariableDeclarationOrPrefixWithUnderscore(identifier, varDecl) {
                    switch (varDecl.parent.parent.kind) {
                        case 214 /* ForStatement */:
                            var forStatement = varDecl.parent.parent;
                            var forInitializer = forStatement.initializer;
                            return [forInitializer.declarations.length === 1 ? deleteNode(forInitializer) : deleteNodeInList(varDecl)];
                        case 216 /* ForOfStatement */:
                            var forOfStatement = varDecl.parent.parent;
                            ts.Debug.assert(forOfStatement.initializer.kind === 227 /* VariableDeclarationList */);
                            var forOfInitializer = forOfStatement.initializer;
                            return [
                                replaceNode(forOfInitializer.declarations[0], ts.createObjectLiteral()),
                                prefixIdentifierWithUnderscore(identifier)
                            ];
                        case 215 /* ForInStatement */:
                            // There is no valid fix in the case of:
                            //  for .. in
                            return [prefixIdentifierWithUnderscore(identifier)];
                        default:
                            var variableStatement = varDecl.parent.parent;
                            if (variableStatement.declarationList.declarations.length === 1) {
                                return [deleteNode(variableStatement)];
                            }
                            else {
                                return [deleteNodeInList(varDecl)];
                            }
                    }
                }
                function deleteNode(n) {
                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNode(sourceFile, n));
                }
                function deleteRange(range) {
                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteRange(sourceFile, range));
                }
                function deleteNodeInList(n) {
                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNodeInList(sourceFile, n));
                }
                function deleteNodeRange(start, end) {
                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNodeRange(sourceFile, start, end));
                }
                function replaceNode(n, newNode) {
                    return makeChange(ts.textChanges.ChangeTracker.fromContext(context).replaceNode(sourceFile, n, newNode));
                }
                function makeChange(changeTracker) {
                    return {
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }),
                        changes: changeTracker.getChanges()
                    };
                }
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code],
            getCodeActions: getActionsForJSDocTypes
        });
        function getActionsForJSDocTypes(context) {
            var sourceFile = context.sourceFile;
            var node = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
            // NOTE: Some locations are not handled yet:
            // MappedTypeNode.typeParameters and SignatureDeclaration.typeParameters, as well as CallExpression.typeArguments
            var decl = ts.findAncestor(node, function (n) {
                return n.kind === 202 /* AsExpression */ ||
                    n.kind === 155 /* CallSignature */ ||
                    n.kind === 156 /* ConstructSignature */ ||
                    n.kind === 228 /* FunctionDeclaration */ ||
                    n.kind === 153 /* GetAccessor */ ||
                    n.kind === 157 /* IndexSignature */ ||
                    n.kind === 172 /* MappedType */ ||
                    n.kind === 151 /* MethodDeclaration */ ||
                    n.kind === 150 /* MethodSignature */ ||
                    n.kind === 146 /* Parameter */ ||
                    n.kind === 149 /* PropertyDeclaration */ ||
                    n.kind === 148 /* PropertySignature */ ||
                    n.kind === 154 /* SetAccessor */ ||
                    n.kind === 231 /* TypeAliasDeclaration */ ||
                    n.kind === 184 /* TypeAssertionExpression */ ||
                    n.kind === 226 /* VariableDeclaration */;
            });
            if (!decl)
                return;
            var checker = context.program.getTypeChecker();
            var jsdocType = decl.type;
            if (!jsdocType)
                return;
            var original = ts.getTextOfNode(jsdocType);
            var type = checker.getTypeFromTypeNode(jsdocType);
            var actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, 8 /* NoTruncation */))];
            if (jsdocType.kind === 270 /* JSDocNullableType */) {
                // for nullable types, suggest the flow-compatible `T | null | undefined`
                // in addition to the jsdoc/closure-compatible `T | null`
                var replacementWithUndefined = checker.typeToString(checker.getNullableType(type, 2048 /* Undefined */), /*enclosingDeclaration*/ undefined, 8 /* NoTruncation */);
                actions.push(createAction(jsdocType, sourceFile.fileName, original, replacementWithUndefined));
            }
            return actions;
        }
        function createAction(declaration, fileName, original, replacement) {
            return {
                description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Change_0_to_1), [original, replacement]),
                changes: [{
                        fileName: fileName,
                        textChanges: [{
                                span: { start: declaration.getStart(), length: declaration.getWidth() },
                                newText: replacement
                            }]
                    }],
            };
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var ChangeTracker = ts.textChanges.ChangeTracker;
        codefix.registerCodeFix({
            errorCodes: [
                ts.Diagnostics.Cannot_find_name_0.code,
                ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
                ts.Diagnostics.Cannot_find_namespace_0.code,
                ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
            ],
            getCodeActions: getImportCodeActions
        });
        var ModuleSpecifierComparison;
        (function (ModuleSpecifierComparison) {
            ModuleSpecifierComparison[ModuleSpecifierComparison["Better"] = 0] = "Better";
            ModuleSpecifierComparison[ModuleSpecifierComparison["Equal"] = 1] = "Equal";
            ModuleSpecifierComparison[ModuleSpecifierComparison["Worse"] = 2] = "Worse";
        })(ModuleSpecifierComparison || (ModuleSpecifierComparison = {}));
        var ImportCodeActionMap = /** @class */ (function () {
            function ImportCodeActionMap() {
                this.symbolIdToActionMap = [];
            }
            ImportCodeActionMap.prototype.addAction = function (symbolId, newAction) {
                var actions = this.symbolIdToActionMap[symbolId];
                if (!actions) {
                    this.symbolIdToActionMap[symbolId] = [newAction];
                    return;
                }
                if (newAction.kind === "CodeChange") {
                    actions.push(newAction);
                    return;
                }
                var updatedNewImports = [];
                for (var _i = 0, _a = this.symbolIdToActionMap[symbolId]; _i < _a.length; _i++) {
                    var existingAction = _a[_i];
                    if (existingAction.kind === "CodeChange") {
                        // only import actions should compare
                        updatedNewImports.push(existingAction);
                        continue;
                    }
                    switch (this.compareModuleSpecifiers(existingAction.moduleSpecifier, newAction.moduleSpecifier)) {
                        case 0 /* Better */:
                            // the new one is not worth considering if it is a new import.
                            // However if it is instead a insertion into existing import, the user might want to use
                            // the module specifier even it is worse by our standards. So keep it.
                            if (newAction.kind === "NewImport") {
                                return;
                            }
                        // falls through
                        case 1 /* Equal */:
                            // the current one is safe. But it is still possible that the new one is worse
                            // than another existing one. For example, you may have new imports from "./foo/bar"
                            // and "bar", when the new one is "bar/bar2" and the current one is "./foo/bar". The new
                            // one and the current one are not comparable (one relative path and one absolute path),
                            // but the new one is worse than the other one, so should not add to the list.
                            updatedNewImports.push(existingAction);
                            break;
                        case 2 /* Worse */:
                            // the existing one is worse, remove from the list.
                            continue;
                    }
                }
                // if we reach here, it means the new one is better or equal to all of the existing ones.
                updatedNewImports.push(newAction);
                this.symbolIdToActionMap[symbolId] = updatedNewImports;
            };
            ImportCodeActionMap.prototype.addActions = function (symbolId, newActions) {
                for (var _i = 0, newActions_1 = newActions; _i < newActions_1.length; _i++) {
                    var newAction = newActions_1[_i];
                    this.addAction(symbolId, newAction);
                }
            };
            ImportCodeActionMap.prototype.getAllActions = function () {
                var result = [];
                for (var key in this.symbolIdToActionMap) {
                    result = ts.concatenate(result, this.symbolIdToActionMap[key]);
                }
                return result;
            };
            ImportCodeActionMap.prototype.compareModuleSpecifiers = function (moduleSpecifier1, moduleSpecifier2) {
                if (moduleSpecifier1 === moduleSpecifier2) {
                    return 1 /* Equal */;
                }
                // if moduleSpecifier1 (ms1) is a substring of ms2, then it is better
                if (moduleSpecifier2.indexOf(moduleSpecifier1) === 0) {
                    return 0 /* Better */;
                }
                if (moduleSpecifier1.indexOf(moduleSpecifier2) === 0) {
                    return 2 /* Worse */;
                }
                // if both are relative paths, and ms1 has fewer levels, then it is better
                if (ts.isExternalModuleNameRelative(moduleSpecifier1) && ts.isExternalModuleNameRelative(moduleSpecifier2)) {
                    var regex = new RegExp(ts.directorySeparator, "g");
                    var moduleSpecifier1LevelCount = (moduleSpecifier1.match(regex) || []).length;
                    var moduleSpecifier2LevelCount = (moduleSpecifier2.match(regex) || []).length;
                    return moduleSpecifier1LevelCount < moduleSpecifier2LevelCount
                        ? 0 /* Better */
                        : moduleSpecifier1LevelCount === moduleSpecifier2LevelCount
                            ? 1 /* Equal */
                            : 2 /* Worse */;
                }
                // the equal cases include when the two specifiers are not comparable.
                return 1 /* Equal */;
            };
            return ImportCodeActionMap;
        }());
        function createCodeAction(description, diagnosticArgs, changes, kind, moduleSpecifier) {
            return {
                description: ts.formatMessage.apply(undefined, [undefined, description].concat(diagnosticArgs)),
                changes: changes,
                kind: kind,
                moduleSpecifier: moduleSpecifier
            };
        }
        function convertToImportCodeFixContext(context) {
            var useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false;
            var checker = context.program.getTypeChecker();
            var symbolToken = ts.getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false);
            return {
                host: context.host,
                newLineCharacter: context.newLineCharacter,
                rulesProvider: context.rulesProvider,
                sourceFile: context.sourceFile,
                checker: checker,
                compilerOptions: context.program.getCompilerOptions(),
                cachedImportDeclarations: [],
                getCanonicalFileName: ts.createGetCanonicalFileName(useCaseSensitiveFileNames),
                symbolName: symbolToken.getText(),
                symbolToken: symbolToken,
            };
        }
        var ImportKind;
        (function (ImportKind) {
            ImportKind[ImportKind["Named"] = 0] = "Named";
            ImportKind[ImportKind["Default"] = 1] = "Default";
            ImportKind[ImportKind["Namespace"] = 2] = "Namespace";
        })(ImportKind = codefix.ImportKind || (codefix.ImportKind = {}));
        function getCodeActionForImport(moduleSymbol, context) {
            var declarations = getImportDeclarations(moduleSymbol, context.checker, context.sourceFile, context.cachedImportDeclarations);
            var actions = [];
            if (context.symbolToken) {
                // It is possible that multiple import statements with the same specifier exist in the file.
                // e.g.
                //
                //     import * as ns from "foo";
                //     import { member1, member2 } from "foo";
                //
                //     member3/**/ <-- cusor here
                //
                // in this case we should provie 2 actions:
                //     1. change "member3" to "ns.member3"
                //     2. add "member3" to the second import statement's import list
                // and it is up to the user to decide which one fits best.
                for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) {
                    var declaration = declarations_13[_i];
                    var namespace = getNamespaceImportName(declaration);
                    if (namespace) {
                        actions.push(getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken));
                    }
                }
            }
            actions.push(getCodeActionForAddImport(moduleSymbol, context, declarations));
            return actions;
        }
        codefix.getCodeActionForImport = getCodeActionForImport;
        function getNamespaceImportName(declaration) {
            if (declaration.kind === 238 /* ImportDeclaration */) {
                var namedBindings = declaration.importClause && declaration.importClause.namedBindings;
                return namedBindings && namedBindings.kind === 240 /* NamespaceImport */ ? namedBindings.name : undefined;
            }
            else {
                return declaration.name;
            }
        }
        // TODO(anhans): This doesn't seem important to cache... just use an iterator instead of creating a new array?
        function getImportDeclarations(moduleSymbol, checker, _a, cachedImportDeclarations) {
            var imports = _a.imports;
            if (cachedImportDeclarations === void 0) { cachedImportDeclarations = []; }
            var moduleSymbolId = ts.getUniqueSymbolId(moduleSymbol, checker);
            var cached = cachedImportDeclarations[moduleSymbolId];
            if (!cached) {
                cached = cachedImportDeclarations[moduleSymbolId] = ts.mapDefined(imports, function (importModuleSpecifier) {
                    return checker.getSymbolAtLocation(importModuleSpecifier) === moduleSymbol ? getImportDeclaration(importModuleSpecifier) : undefined;
                });
            }
            return cached;
        }
        function getImportDeclaration(_a) {
            var parent = _a.parent;
            switch (parent.kind) {
                case 238 /* ImportDeclaration */:
                    return parent;
                case 248 /* ExternalModuleReference */:
                    return parent.parent;
                default:
                    ts.Debug.assert(parent.kind === 244 /* ExportDeclaration */);
                    // Ignore these, can't add imports to them.
                    return undefined;
            }
        }
        function getCodeActionForNewImport(context, moduleSpecifier) {
            var kind = context.kind, sourceFile = context.sourceFile, newLineCharacter = context.newLineCharacter, symbolName = context.symbolName;
            var lastImportDeclaration = ts.findLast(sourceFile.statements, ts.isAnyImportSyntax);
            var moduleSpecifierWithoutQuotes = ts.stripQuotes(moduleSpecifier);
            var importDecl = ts.createImportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, createImportClauseOfKind(kind, symbolName), createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes));
            var changes = ChangeTracker.with(context, function (changeTracker) {
                if (lastImportDeclaration) {
                    changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: newLineCharacter });
                }
                else {
                    changeTracker.insertNodeAt(sourceFile, ts.getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + newLineCharacter + newLineCharacter });
                }
            });
            // if this file doesn't have any import statements, insert an import statement and then insert a new line
            // between the only import statement and user code. Otherwise just insert the statement because chances
            // are there are already a new line seperating code and import statements.
            return createCodeAction(ts.Diagnostics.Import_0_from_1, [symbolName, moduleSpecifierWithoutQuotes], changes, "NewImport", moduleSpecifierWithoutQuotes);
        }
        function createStringLiteralWithQuoteStyle(sourceFile, text) {
            var literal = ts.createLiteral(text);
            var firstModuleSpecifier = ts.firstOrUndefined(sourceFile.imports);
            literal.singleQuote = !!firstModuleSpecifier && !ts.isStringDoubleQuoted(firstModuleSpecifier, sourceFile);
            return literal;
        }
        function createImportClauseOfKind(kind, symbolName) {
            var id = ts.createIdentifier(symbolName);
            switch (kind) {
                case 1 /* Default */:
                    return ts.createImportClause(id, /*namedBindings*/ undefined);
                case 2 /* Namespace */:
                    return ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(id));
                case 0 /* Named */:
                    return ts.createImportClause(/*name*/ undefined, ts.createNamedImports([ts.createImportSpecifier(/*propertyName*/ undefined, id)]));
                default:
                    ts.Debug.assertNever(kind);
            }
        }
        function getModuleSpecifierForNewImport(sourceFile, moduleSymbol, options, getCanonicalFileName, host) {
            var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
            var sourceDirectory = ts.getDirectoryPath(sourceFile.fileName);
            return tryGetModuleNameFromAmbientModule(moduleSymbol) ||
                tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) ||
                tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) ||
                tryGetModuleNameFromBaseUrl(options, moduleFileName, getCanonicalFileName) ||
                options.rootDirs && tryGetModuleNameFromRootDirs(options.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
                ts.removeFileExtension(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName));
        }
        function tryGetModuleNameFromAmbientModule(moduleSymbol) {
            var decl = moduleSymbol.valueDeclaration;
            if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) {
                return decl.name.text;
            }
        }
        function tryGetModuleNameFromBaseUrl(options, moduleFileName, getCanonicalFileName) {
            if (!options.baseUrl) {
                return undefined;
            }
            var relativeName = getRelativePathIfInDirectory(moduleFileName, options.baseUrl, getCanonicalFileName);
            if (!relativeName) {
                return undefined;
            }
            var relativeNameWithIndex = ts.removeFileExtension(relativeName);
            relativeName = removeExtensionAndIndexPostFix(relativeName);
            if (options.paths) {
                for (var key in options.paths) {
                    for (var _i = 0, _a = options.paths[key]; _i < _a.length; _i++) {
                        var pattern = _a[_i];
                        var indexOfStar = pattern.indexOf("*");
                        if (indexOfStar === 0 && pattern.length === 1) {
                            continue;
                        }
                        else if (indexOfStar !== -1) {
                            var prefix = pattern.substr(0, indexOfStar);
                            var suffix = pattern.substr(indexOfStar + 1);
                            if (relativeName.length >= prefix.length + suffix.length &&
                                ts.startsWith(relativeName, prefix) &&
                                ts.endsWith(relativeName, suffix)) {
                                var matchedStar = relativeName.substr(prefix.length, relativeName.length - suffix.length);
                                return key.replace("\*", matchedStar);
                            }
                        }
                        else if (pattern === relativeName || pattern === relativeNameWithIndex) {
                            return key;
                        }
                    }
                }
            }
            return relativeName;
        }
        function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) {
            var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
            if (normalizedTargetPath === undefined) {
                return undefined;
            }
            var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName);
            var relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath, getCanonicalFileName) : normalizedTargetPath;
            return ts.removeFileExtension(relativePath);
        }
        function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) {
            var roots = ts.getEffectiveTypeRoots(options, host);
            return roots && ts.firstDefined(roots, function (unNormalizedTypeRoot) {
                var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName);
                if (ts.startsWith(moduleFileName, typeRoot)) {
                    return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1));
                }
            });
        }
        function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) {
            if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) {
                // nothing to do here
                return undefined;
            }
            var parts = getNodeModulePathParts(moduleFileName);
            if (!parts) {
                return undefined;
            }
            // Simplify the full file path to something that can be resolved by Node.
            // If the module could be imported by a directory name, use that directory's name
            var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
            // Get a path that's relative to node_modules or the importing file's path
            moduleSpecifier = getNodeResolvablePath(moduleSpecifier);
            // If the module was found in @types, get the actual Node package name
            return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier);
            function getDirectoryOrExtensionlessFileName(path) {
                // If the file is the main module, it can be imported by the package name
                var packageRootPath = path.substring(0, parts.packageRootIndex);
                var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
                if (host.fileExists(packageJsonPath)) {
                    var packageJsonContent = JSON.parse(host.readFile(packageJsonPath));
                    if (packageJsonContent) {
                        var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
                        if (mainFileRelative) {
                            var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
                            if (mainExportFile === getCanonicalFileName(path)) {
                                return packageRootPath;
                            }
                        }
                    }
                }
                // We still have a file name - remove the extension
                var fullModulePathWithoutExtension = ts.removeFileExtension(path);
                // If the file is /index, it can be imported by its directory name
                if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") {
                    return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex);
                }
                return fullModulePathWithoutExtension;
            }
            function getNodeResolvablePath(path) {
                var basePath = path.substring(0, parts.topLevelNodeModulesIndex);
                if (sourceDirectory.indexOf(basePath) === 0) {
                    // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
                    return path.substring(parts.topLevelPackageNameIndex + 1);
                }
                else {
                    return getRelativePath(path, sourceDirectory, getCanonicalFileName);
                }
            }
        }
        function getNodeModulePathParts(fullPath) {
            // If fullPath can't be valid module file within node_modules, returns undefined.
            // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
            // Returns indices:                       ^            ^                                                      ^             ^
            var topLevelNodeModulesIndex = 0;
            var topLevelPackageNameIndex = 0;
            var packageRootIndex = 0;
            var fileNameIndex = 0;
            var States;
            (function (States) {
                States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules";
                States[States["NodeModules"] = 1] = "NodeModules";
                States[States["Scope"] = 2] = "Scope";
                States[States["PackageContent"] = 3] = "PackageContent";
            })(States || (States = {}));
            var partStart = 0;
            var partEnd = 0;
            var state = 0 /* BeforeNodeModules */;
            while (partEnd >= 0) {
                partStart = partEnd;
                partEnd = fullPath.indexOf("/", partStart + 1);
                switch (state) {
                    case 0 /* BeforeNodeModules */:
                        if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
                            topLevelNodeModulesIndex = partStart;
                            topLevelPackageNameIndex = partEnd;
                            state = 1 /* NodeModules */;
                        }
                        break;
                    case 1 /* NodeModules */:
                    case 2 /* Scope */:
                        if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") {
                            state = 2 /* Scope */;
                        }
                        else {
                            packageRootIndex = partEnd;
                            state = 3 /* PackageContent */;
                        }
                        break;
                    case 3 /* PackageContent */:
                        if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
                            state = 1 /* NodeModules */;
                        }
                        else {
                            state = 3 /* PackageContent */;
                        }
                        break;
                }
            }
            fileNameIndex = partStart;
            return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined;
        }
        function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) {
            return ts.firstDefined(rootDirs, function (rootDir) { return getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); });
        }
        function removeExtensionAndIndexPostFix(fileName) {
            fileName = ts.removeFileExtension(fileName);
            if (ts.endsWith(fileName, "/index")) {
                fileName = fileName.substr(0, fileName.length - 6 /* "/index".length */);
            }
            return fileName;
        }
        function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) {
            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
            return ts.isRootedDiskPath(relativePath) || ts.startsWith(relativePath, "..") ? undefined : relativePath;
        }
        function getRelativePath(path, directoryPath, getCanonicalFileName) {
            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
            return !ts.pathIsRelative(relativePath) ? "./" + relativePath : relativePath;
        }
        function getCodeActionForAddImport(moduleSymbol, ctx, declarations) {
            var fromExistingImport = ts.firstDefined(declarations, function (declaration) {
                if (declaration.kind === 238 /* ImportDeclaration */ && declaration.importClause) {
                    var changes = tryUpdateExistingImport(ctx, declaration.importClause);
                    if (changes) {
                        var moduleSpecifierWithoutQuotes = ts.stripQuotes(declaration.moduleSpecifier.getText());
                        return createCodeAction(ts.Diagnostics.Add_0_to_existing_import_declaration_from_1, [ctx.symbolName, moduleSpecifierWithoutQuotes], changes, "InsertingIntoExistingImport", moduleSpecifierWithoutQuotes);
                    }
                }
            });
            if (fromExistingImport) {
                return fromExistingImport;
            }
            var moduleSpecifier = ts.firstDefined(declarations, moduleSpecifierFromAnyImport)
                || getModuleSpecifierForNewImport(ctx.sourceFile, moduleSymbol, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
            return getCodeActionForNewImport(ctx, moduleSpecifier);
        }
        function moduleSpecifierFromAnyImport(node) {
            var expression = node.kind === 238 /* ImportDeclaration */
                ? node.moduleSpecifier
                : node.moduleReference.kind === 248 /* ExternalModuleReference */
                    ? node.moduleReference.expression
                    : undefined;
            return expression && ts.isStringLiteral(expression) ? expression.text : undefined;
        }
        function tryUpdateExistingImport(context, importClause) {
            var symbolName = context.symbolName, sourceFile = context.sourceFile, kind = context.kind;
            var name = importClause.name, namedBindings = importClause.namedBindings;
            switch (kind) {
                case 1 /* Default */:
                    return name ? undefined : ChangeTracker.with(context, function (t) {
                        return t.replaceNode(sourceFile, importClause, ts.createImportClause(ts.createIdentifier(symbolName), namedBindings));
                    });
                case 0 /* Named */: {
                    var newImportSpecifier_1 = ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(symbolName));
                    if (namedBindings && namedBindings.kind === 241 /* NamedImports */ && namedBindings.elements.length !== 0) {
                        // There are already named imports; add another.
                        return ChangeTracker.with(context, function (t) { return t.insertNodeInListAfter(sourceFile, namedBindings.elements[namedBindings.elements.length - 1], newImportSpecifier_1); });
                    }
                    if (!namedBindings || namedBindings.kind === 241 /* NamedImports */ && namedBindings.elements.length === 0) {
                        return ChangeTracker.with(context, function (t) {
                            return t.replaceNode(sourceFile, importClause, ts.createImportClause(name, ts.createNamedImports([newImportSpecifier_1])));
                        });
                    }
                    return undefined;
                }
                case 2 /* Namespace */:
                    return namedBindings ? undefined : ChangeTracker.with(context, function (t) {
                        return t.replaceNode(sourceFile, importClause, ts.createImportClause(name, ts.createNamespaceImport(ts.createIdentifier(symbolName))));
                    });
                default:
                    ts.Debug.assertNever(kind);
            }
        }
        function getCodeActionForUseExistingNamespaceImport(namespacePrefix, context, symbolToken) {
            var symbolName = context.symbolName, sourceFile = context.sourceFile;
            /**
             * Cases:
             *     import * as ns from "mod"
             *     import default, * as ns from "mod"
             *     import ns = require("mod")
             *
             * Because there is no import list, we alter the reference to include the
             * namespace instead of altering the import declaration. For example, "foo" would
             * become "ns.foo"
             */
            return createCodeAction(ts.Diagnostics.Change_0_to_1, [symbolName, namespacePrefix + "." + symbolName], ChangeTracker.with(context, function (tracker) {
                return tracker.replaceNode(sourceFile, symbolToken, ts.createPropertyAccess(ts.createIdentifier(namespacePrefix), symbolName));
            }), "CodeChange", 
            /*moduleSpecifier*/ undefined);
        }
        function getImportCodeActions(context) {
            var importFixContext = convertToImportCodeFixContext(context);
            return context.errorCode === ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
                ? getActionsForUMDImport(importFixContext)
                : getActionsForNonUMDImport(importFixContext, context.program.getSourceFiles(), context.cancellationToken);
        }
        function getActionsForUMDImport(context) {
            var checker = context.checker, symbolToken = context.symbolToken;
            var umdSymbol = checker.getSymbolAtLocation(symbolToken);
            var symbol;
            var symbolName;
            if (umdSymbol.flags & 2097152 /* Alias */) {
                symbol = checker.getAliasedSymbol(umdSymbol);
                symbolName = context.symbolName;
            }
            else if (ts.isJsxOpeningLikeElement(symbolToken.parent) && symbolToken.parent.tagName === symbolToken) {
                // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
                symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, 107455 /* Value */));
                symbolName = symbol.name;
            }
            else {
                ts.Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here");
            }
            return getCodeActionForImport(symbol, __assign({}, context, { symbolName: symbolName, kind: 2 /* Namespace */ }));
        }
        function getActionsForNonUMDImport(context, allSourceFiles, cancellationToken) {
            var sourceFile = context.sourceFile, checker = context.checker, symbolName = context.symbolName, symbolToken = context.symbolToken;
            // "default" is a keyword and not a legal identifier for the import, so we don't expect it here
            ts.Debug.assert(symbolName !== "default");
            var symbolIdActionMap = new ImportCodeActionMap();
            var currentTokenMeaning = ts.getMeaningFromLocation(symbolToken);
            forEachExternalModule(checker, allSourceFiles, function (moduleSymbol) {
                if (moduleSymbol === sourceFile.symbol) {
                    return;
                }
                cancellationToken.throwIfCancellationRequested();
                // check the default export
                var defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
                if (defaultExport) {
                    var localSymbol = ts.getLocalSymbolForExportDefault(defaultExport);
                    if (localSymbol && localSymbol.escapedName === symbolName && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
                        // check if this symbol is already used
                        var symbolId = ts.getUniqueSymbolId(localSymbol, checker);
                        symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, __assign({}, context, { kind: 1 /* Default */ })));
                    }
                }
                // check exports with the same name
                var exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol);
                if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
                    var symbolId = ts.getUniqueSymbolId(exportSymbolWithIdenticalName, checker);
                    symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, __assign({}, context, { kind: 0 /* Named */ })));
                }
            });
            return symbolIdActionMap.getAllActions();
        }
        function checkSymbolHasMeaning(_a, meaning) {
            var declarations = _a.declarations;
            return ts.some(declarations, function (decl) { return !!(ts.getMeaningFromDeclaration(decl) & meaning); });
        }
        function forEachExternalModule(checker, allSourceFiles, cb) {
            for (var _i = 0, _a = checker.getAmbientModules(); _i < _a.length; _i++) {
                var ambient = _a[_i];
                cb(ambient);
            }
            for (var _b = 0, allSourceFiles_1 = allSourceFiles; _b < allSourceFiles_1.length; _b++) {
                var sourceFile = allSourceFiles_1[_b];
                if (ts.isExternalOrCommonJsModule(sourceFile)) {
                    cb(sourceFile.symbol);
                }
            }
        }
        codefix.forEachExternalModule = forEachExternalModule;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: getApplicableDiagnosticCodes(),
            getCodeActions: getDisableJsDiagnosticsCodeActions
        });
        function getApplicableDiagnosticCodes() {
            var allDiagnostcs = ts.Diagnostics;
            return Object.keys(allDiagnostcs)
                .filter(function (d) { return allDiagnostcs[d] && allDiagnostcs[d].category === ts.DiagnosticCategory.Error; })
                .map(function (d) { return allDiagnostcs[d].code; });
        }
        function getIgnoreCommentLocationForLocation(sourceFile, position, newLineCharacter) {
            var line = ts.getLineAndCharacterOfPosition(sourceFile, position).line;
            var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
            var startPosition = ts.getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
            // First try to see if we can put the '// @ts-ignore' on the previous line.
            // We need to make sure that we are not in the middle of a string literal or a comment.
            // We also want to check if the previous line holds a comment for a node on the next line
            // if so, we do not want to separate the node from its comment if we can.
            if (!ts.isInComment(sourceFile, startPosition) && !ts.isInString(sourceFile, startPosition) && !ts.isInTemplateString(sourceFile, startPosition)) {
                var token = ts.getTouchingToken(sourceFile, startPosition, /*includeJsDocComment*/ false);
                var tokenLeadingCommnets = ts.getLeadingCommentRangesOfNode(token, sourceFile);
                if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) {
                    return {
                        span: { start: startPosition, length: 0 },
                        newText: "// @ts-ignore" + newLineCharacter
                    };
                }
            }
            // If all fails, add an extra new line immediately before the error span.
            return {
                span: { start: position, length: 0 },
                newText: (position === startPosition ? "" : newLineCharacter) + "// @ts-ignore" + newLineCharacter
            };
        }
        function getDisableJsDiagnosticsCodeActions(context) {
            var sourceFile = context.sourceFile, program = context.program, newLineCharacter = context.newLineCharacter, span = context.span;
            if (!ts.isInJavaScriptFile(sourceFile) || !ts.isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
                return undefined;
            }
            return [{
                    description: ts.getLocaleSpecificMessage(ts.Diagnostics.Ignore_this_error_message),
                    changes: [{
                            fileName: sourceFile.fileName,
                            textChanges: [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)]
                        }]
                },
                {
                    description: ts.getLocaleSpecificMessage(ts.Diagnostics.Disable_checking_for_this_file),
                    changes: [{
                            fileName: sourceFile.fileName,
                            textChanges: [{
                                    span: {
                                        start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0,
                                        length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0
                                    },
                                    newText: "// @ts-nocheck" + newLineCharacter
                                }]
                        }]
                }];
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        function newNodesToChanges(newNodes, insertAfter, context) {
            var sourceFile = context.sourceFile;
            var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
            for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) {
                var newNode = newNodes_1[_i];
                changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter });
            }
            var changes = changeTracker.getChanges();
            if (!ts.some(changes)) {
                return changes;
            }
            ts.Debug.assert(changes.length === 1);
            var consolidatedChanges = [{
                    fileName: changes[0].fileName,
                    textChanges: [{
                            span: changes[0].textChanges[0].span,
                            newText: changes[0].textChanges.reduce(function (prev, cur) { return prev + cur.newText; }, "")
                        }]
                }];
            return consolidatedChanges;
        }
        codefix.newNodesToChanges = newNodesToChanges;
        /**
         * Finds members of the resolved type that are missing in the class pointed to by class decl
         * and generates source code for the missing members.
         * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
         * @returns Empty string iff there are no member insertions.
         */
        function createMissingMemberNodes(classDeclaration, possiblyMissingSymbols, checker) {
            var classMembers = classDeclaration.symbol.members;
            var missingMembers = possiblyMissingSymbols.filter(function (symbol) { return !classMembers.has(symbol.escapedName); });
            var newNodes = [];
            for (var _i = 0, missingMembers_1 = missingMembers; _i < missingMembers_1.length; _i++) {
                var symbol = missingMembers_1[_i];
                var newNode = createNewNodeForMemberSymbol(symbol, classDeclaration, checker);
                if (newNode) {
                    if (Array.isArray(newNode)) {
                        newNodes = newNodes.concat(newNode);
                    }
                    else {
                        newNodes.push(newNode);
                    }
                }
            }
            return newNodes;
        }
        codefix.createMissingMemberNodes = createMissingMemberNodes;
        /**
         * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
         */
        function createNewNodeForMemberSymbol(symbol, enclosingDeclaration, checker) {
            var declarations = symbol.getDeclarations();
            if (!(declarations && declarations.length)) {
                return undefined;
            }
            var declaration = declarations[0];
            // Clone name to remove leading trivia.
            var name = ts.getSynthesizedClone(ts.getNameOfDeclaration(declaration));
            var visibilityModifier = createVisibilityModifier(ts.getModifierFlags(declaration));
            var modifiers = visibilityModifier ? ts.createNodeArray([visibilityModifier]) : undefined;
            var type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
            var optional = !!(symbol.flags & 16777216 /* Optional */);
            switch (declaration.kind) {
                case 153 /* GetAccessor */:
                case 154 /* SetAccessor */:
                case 148 /* PropertySignature */:
                case 149 /* PropertyDeclaration */:
                    var typeNode = checker.typeToTypeNode(type, enclosingDeclaration);
                    var property = ts.createProperty(
                    /*decorators*/ undefined, modifiers, name, optional ? ts.createToken(55 /* QuestionToken */) : undefined, typeNode, 
                    /*initializer*/ undefined);
                    return property;
                case 150 /* MethodSignature */:
                case 151 /* MethodDeclaration */:
                    // The signature for the implementation appears as an entry in `signatures` iff
                    // there is only one signature.
                    // If there are overloads and an implementation signature, it appears as an
                    // extra declaration that isn't a signature for `type`.
                    // If there is more than one overload but no implementation signature
                    // (eg: an abstract method or interface declaration), there is a 1-1
                    // correspondence of declarations and signatures.
                    var signatures = checker.getSignaturesOfType(type, 0 /* Call */);
                    if (!ts.some(signatures)) {
                        return undefined;
                    }
                    if (declarations.length === 1) {
                        ts.Debug.assert(signatures.length === 1);
                        var signature = signatures[0];
                        return signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody());
                    }
                    var signatureDeclarations = [];
                    for (var i = 0; i < signatures.length; i++) {
                        var signature = signatures[i];
                        var methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration);
                        if (methodDeclaration) {
                            signatureDeclarations.push(methodDeclaration);
                        }
                    }
                    if (declarations.length > signatures.length) {
                        var signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1]);
                        var methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody());
                        if (methodDeclaration) {
                            signatureDeclarations.push(methodDeclaration);
                        }
                    }
                    else {
                        ts.Debug.assert(declarations.length === signatures.length);
                        var methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, optional, modifiers);
                        signatureDeclarations.push(methodImplementingSignatures);
                    }
                    return signatureDeclarations;
                default:
                    return undefined;
            }
            function signatureToMethodDeclaration(signature, enclosingDeclaration, body) {
                var signatureDeclaration = checker.signatureToSignatureDeclaration(signature, 151 /* MethodDeclaration */, enclosingDeclaration, ts.NodeBuilderFlags.SuppressAnyReturnType);
                if (signatureDeclaration) {
                    signatureDeclaration.decorators = undefined;
                    signatureDeclaration.modifiers = modifiers;
                    signatureDeclaration.name = name;
                    signatureDeclaration.questionToken = optional ? ts.createToken(55 /* QuestionToken */) : undefined;
                    signatureDeclaration.body = body;
                }
                return signatureDeclaration;
            }
        }
        function createMethodFromCallExpression(callExpression, methodName, includeTypeScriptSyntax, makeStatic) {
            var parameters = createDummyParameters(callExpression.arguments.length, /*names*/ undefined, /*minArgumentCount*/ undefined, includeTypeScriptSyntax);
            var typeParameters;
            if (includeTypeScriptSyntax) {
                var typeArgCount = ts.length(callExpression.typeArguments);
                for (var i = 0; i < typeArgCount; i++) {
                    var name = typeArgCount < 8 ? String.fromCharCode(84 /* T */ + i) : "T" + i;
                    var typeParameter = ts.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined);
                    (typeParameters ? typeParameters : typeParameters = []).push(typeParameter);
                }
            }
            var newMethod = ts.createMethod(
            /*decorators*/ undefined, 
            /*modifiers*/ makeStatic ? [ts.createToken(115 /* StaticKeyword */)] : undefined, 
            /*asteriskToken*/ undefined, methodName, 
            /*questionToken*/ undefined, typeParameters, parameters, 
            /*type*/ includeTypeScriptSyntax ? ts.createKeywordTypeNode(119 /* AnyKeyword */) : undefined, createStubbedMethodBody());
            return newMethod;
        }
        codefix.createMethodFromCallExpression = createMethodFromCallExpression;
        function createDummyParameters(argCount, names, minArgumentCount, addAnyType) {
            var parameters = [];
            for (var i = 0; i < argCount; i++) {
                var newParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, 
                /*name*/ names && names[i] || "arg" + i, 
                /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? ts.createToken(55 /* QuestionToken */) : undefined, 
                /*type*/ addAnyType ? ts.createKeywordTypeNode(119 /* AnyKeyword */) : undefined, 
                /*initializer*/ undefined);
                parameters.push(newParameter);
            }
            return parameters;
        }
        function createMethodImplementingSignatures(signatures, name, optional, modifiers) {
            /** This is *a* signature with the maximal number of arguments,
             * such that if there is a "maximal" signature without rest arguments,
             * this is one of them.
             */
            var maxArgsSignature = signatures[0];
            var minArgumentCount = signatures[0].minArgumentCount;
            var someSigHasRestParameter = false;
            for (var i = 0; i < signatures.length; i++) {
                var sig = signatures[i];
                minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
                if (sig.hasRestParameter) {
                    someSigHasRestParameter = true;
                }
                if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) {
                    maxArgsSignature = sig;
                }
            }
            var maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
            var maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(function (symbol) { return symbol.name; });
            var parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, minArgumentCount, /*addAnyType*/ true);
            if (someSigHasRestParameter) {
                var anyArrayType = ts.createArrayTypeNode(ts.createKeywordTypeNode(119 /* AnyKeyword */));
                var restParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createToken(24 /* DotDotDotToken */), maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", 
                /*questionToken*/ maxNonRestArgs >= minArgumentCount ? ts.createToken(55 /* QuestionToken */) : undefined, anyArrayType, 
                /*initializer*/ undefined);
                parameters.push(restParameter);
            }
            return createStubbedMethod(modifiers, name, optional, 
            /*typeParameters*/ undefined, parameters, 
            /*returnType*/ undefined);
        }
        function createStubbedMethod(modifiers, name, optional, typeParameters, parameters, returnType) {
            return ts.createMethod(
            /*decorators*/ undefined, modifiers, 
            /*asteriskToken*/ undefined, name, optional ? ts.createToken(55 /* QuestionToken */) : undefined, typeParameters, parameters, returnType, createStubbedMethodBody());
        }
        codefix.createStubbedMethod = createStubbedMethod;
        function createStubbedMethodBody() {
            return ts.createBlock([ts.createThrow(ts.createNew(ts.createIdentifier("Error"), 
                /*typeArguments*/ undefined, [ts.createLiteral("Method not implemented.")]))], 
            /*multiline*/ true);
        }
        function createVisibilityModifier(flags) {
            if (flags & 4 /* Public */) {
                return ts.createToken(114 /* PublicKeyword */);
            }
            else if (flags & 16 /* Protected */) {
                return ts.createToken(113 /* ProtectedKeyword */);
            }
            return undefined;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [
                // Variable declarations
                ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code,
                // Variable uses
                ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code,
                // Parameter declarations
                ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code,
                ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code,
                // Get Accessor declarations
                ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code,
                ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code,
                // Set Accessor declarations
                ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code,
                // Property declarations
                ts.Diagnostics.Member_0_implicitly_has_an_1_type.code,
            ],
            getCodeActions: getActionsForAddExplicitTypeAnnotation
        });
        function getActionsForAddExplicitTypeAnnotation(_a) {
            var sourceFile = _a.sourceFile, program = _a.program, start = _a.span.start, errorCode = _a.errorCode, cancellationToken = _a.cancellationToken;
            var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
            var writer;
            if (ts.isInJavaScriptFile(token)) {
                return undefined;
            }
            switch (token.kind) {
                case 71 /* Identifier */:
                case 24 /* DotDotDotToken */:
                case 114 /* PublicKeyword */:
                case 112 /* PrivateKeyword */:
                case 113 /* ProtectedKeyword */:
                case 131 /* ReadonlyKeyword */:
                    // Allowed
                    break;
                default:
                    return undefined;
            }
            var containingFunction = ts.getContainingFunction(token);
            var checker = program.getTypeChecker();
            switch (errorCode) {
                // Variable and Property declarations
                case ts.Diagnostics.Member_0_implicitly_has_an_1_type.code:
                case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
                    return getCodeActionForVariableDeclaration(token.parent);
                case ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code:
                    return getCodeActionForVariableUsage(token);
                // Parameter declarations
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
                    if (ts.isSetAccessor(containingFunction)) {
                        return getCodeActionForSetAccessor(containingFunction);
                    }
                // falls through
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
                    return getCodeActionForParameters(token.parent);
                // Get Accessor declarations
                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code:
                case ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code:
                    return ts.isGetAccessor(containingFunction) ? getCodeActionForGetAccessor(containingFunction) : undefined;
                // Set Accessor declarations
                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code:
                    return ts.isSetAccessor(containingFunction) ? getCodeActionForSetAccessor(containingFunction) : undefined;
            }
            return undefined;
            function getCodeActionForVariableDeclaration(declaration) {
                if (!ts.isIdentifier(declaration.name)) {
                    return undefined;
                }
                var type = inferTypeForVariableFromUsage(declaration.name);
                var typeString = type && typeToString(type, declaration);
                if (!typeString) {
                    return undefined;
                }
                return createCodeActions(declaration.name.getText(), declaration.name.getEnd(), ": " + typeString);
            }
            function getCodeActionForVariableUsage(token) {
                var symbol = checker.getSymbolAtLocation(token);
                return symbol && symbol.valueDeclaration && getCodeActionForVariableDeclaration(symbol.valueDeclaration);
            }
            function isApplicableFunctionForInference(declaration) {
                switch (declaration.kind) {
                    case 228 /* FunctionDeclaration */:
                    case 151 /* MethodDeclaration */:
                    case 152 /* Constructor */:
                        return true;
                    case 186 /* FunctionExpression */:
                        return !!declaration.name;
                }
                return false;
            }
            function getCodeActionForParameters(parameterDeclaration) {
                if (!ts.isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) {
                    return undefined;
                }
                var types = inferTypeForParametersFromUsage(containingFunction) ||
                    ts.map(containingFunction.parameters, function (p) { return ts.isIdentifier(p.name) && inferTypeForVariableFromUsage(p.name); });
                if (!types) {
                    return undefined;
                }
                var textChanges = ts.zipWith(containingFunction.parameters, types, function (parameter, type) {
                    if (type && !parameter.type && !parameter.initializer) {
                        var typeString = typeToString(type, containingFunction);
                        return typeString ? {
                            span: { start: parameter.end, length: 0 },
                            newText: ": " + typeString
                        } : undefined;
                    }
                }).filter(function (c) { return !!c; });
                return textChanges.length ? [{
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Infer_parameter_types_from_usage), [parameterDeclaration.name.getText()]),
                        changes: [{
                                fileName: sourceFile.fileName,
                                textChanges: textChanges
                            }]
                    }] : undefined;
            }
            function getCodeActionForSetAccessor(setAccessorDeclaration) {
                var setAccessorParameter = setAccessorDeclaration.parameters[0];
                if (!setAccessorParameter || !ts.isIdentifier(setAccessorDeclaration.name) || !ts.isIdentifier(setAccessorParameter.name)) {
                    return undefined;
                }
                var type = inferTypeForVariableFromUsage(setAccessorDeclaration.name) ||
                    inferTypeForVariableFromUsage(setAccessorParameter.name);
                var typeString = type && typeToString(type, containingFunction);
                if (!typeString) {
                    return undefined;
                }
                return createCodeActions(setAccessorDeclaration.name.getText(), setAccessorParameter.name.getEnd(), ": " + typeString);
            }
            function getCodeActionForGetAccessor(getAccessorDeclaration) {
                if (!ts.isIdentifier(getAccessorDeclaration.name)) {
                    return undefined;
                }
                var type = inferTypeForVariableFromUsage(getAccessorDeclaration.name);
                var typeString = type && typeToString(type, containingFunction);
                if (!typeString) {
                    return undefined;
                }
                var closeParenToken = getFirstChildOfKind(getAccessorDeclaration, sourceFile, 20 /* CloseParenToken */);
                return createCodeActions(getAccessorDeclaration.name.getText(), closeParenToken.getEnd(), ": " + typeString);
            }
            function createCodeActions(name, start, typeString) {
                return [{
                        description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Infer_type_of_0_from_usage), [name]),
                        changes: [{
                                fileName: sourceFile.fileName,
                                textChanges: [{
                                        span: { start: start, length: 0 },
                                        newText: typeString
                                    }]
                            }]
                    }];
            }
            function getReferences(token) {
                var references = ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), token.getSourceFile(), token.getStart());
                ts.Debug.assert(!!references, "Found no references!");
                ts.Debug.assert(references.length === 1, "Found more references than expected");
                return ts.map(references[0].references, function (r) { return ts.getTokenAtPosition(program.getSourceFile(r.fileName), r.textSpan.start, /*includeJsDocComment*/ false); });
            }
            function inferTypeForVariableFromUsage(token) {
                return InferFromReference.inferTypeFromReferences(getReferences(token), checker, cancellationToken);
            }
            function inferTypeForParametersFromUsage(containingFunction) {
                switch (containingFunction.kind) {
                    case 152 /* Constructor */:
                    case 186 /* FunctionExpression */:
                    case 228 /* FunctionDeclaration */:
                    case 151 /* MethodDeclaration */:
                        var isConstructor = containingFunction.kind === 152 /* Constructor */;
                        var searchToken = isConstructor ?
                            getFirstChildOfKind(containingFunction, sourceFile, 123 /* ConstructorKeyword */) :
                            containingFunction.name;
                        if (searchToken) {
                            return InferFromReference.inferTypeForParametersFromReferences(getReferences(searchToken), containingFunction, checker, cancellationToken);
                        }
                }
            }
            function getTypeAccessiblityWriter() {
                if (!writer) {
                    var str_1 = "";
                    var typeIsAccessible_1 = true;
                    var writeText = function (text) { return str_1 += text; };
                    writer = {
                        string: function () { return typeIsAccessible_1 ? str_1 : undefined; },
                        writeKeyword: writeText,
                        writeOperator: writeText,
                        writePunctuation: writeText,
                        writeSpace: writeText,
                        writeStringLiteral: writeText,
                        writeParameter: writeText,
                        writeProperty: writeText,
                        writeSymbol: writeText,
                        writeLine: function () { return str_1 += " "; },
                        increaseIndent: ts.noop,
                        decreaseIndent: ts.noop,
                        clear: function () { str_1 = ""; typeIsAccessible_1 = true; },
                        trackSymbol: function (symbol, declaration, meaning) {
                            if (checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility !== 0 /* Accessible */) {
                                typeIsAccessible_1 = false;
                            }
                        },
                        reportInaccessibleThisError: function () { typeIsAccessible_1 = false; },
                        reportPrivateInBaseOfClassExpression: function () { typeIsAccessible_1 = false; },
                    };
                }
                writer.clear();
                return writer;
            }
            function typeToString(type, enclosingDeclaration) {
                var writer = getTypeAccessiblityWriter();
                checker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration);
                return writer.string();
            }
            function getFirstChildOfKind(node, sourcefile, kind) {
                for (var _i = 0, _a = node.getChildren(sourcefile); _i < _a.length; _i++) {
                    var child = _a[_i];
                    if (child.kind === kind)
                        return child;
                }
                return undefined;
            }
        }
        var InferFromReference;
        (function (InferFromReference) {
            function inferTypeFromReferences(references, checker, cancellationToken) {
                var usageContext = {};
                for (var _i = 0, references_1 = references; _i < references_1.length; _i++) {
                    var reference = references_1[_i];
                    cancellationToken.throwIfCancellationRequested();
                    inferTypeFromContext(reference, checker, usageContext);
                }
                return getTypeFromUsageContext(usageContext, checker);
            }
            InferFromReference.inferTypeFromReferences = inferTypeFromReferences;
            function inferTypeForParametersFromReferences(references, declaration, checker, cancellationToken) {
                if (declaration.parameters) {
                    var usageContext = {};
                    for (var _i = 0, references_2 = references; _i < references_2.length; _i++) {
                        var reference = references_2[_i];
                        cancellationToken.throwIfCancellationRequested();
                        inferTypeFromContext(reference, checker, usageContext);
                    }
                    var isConstructor = declaration.kind === 152 /* Constructor */;
                    var callContexts = isConstructor ? usageContext.constructContexts : usageContext.callContexts;
                    if (callContexts) {
                        var paramTypes = [];
                        for (var parameterIndex = 0; parameterIndex < declaration.parameters.length; parameterIndex++) {
                            var types = [];
                            var isRestParameter_1 = ts.isRestParameter(declaration.parameters[parameterIndex]);
                            for (var _a = 0, callContexts_1 = callContexts; _a < callContexts_1.length; _a++) {
                                var callContext = callContexts_1[_a];
                                if (callContext.argumentTypes.length > parameterIndex) {
                                    if (isRestParameter_1) {
                                        types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); }));
                                    }
                                    else {
                                        types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex]));
                                    }
                                }
                            }
                            if (types.length) {
                                var type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true));
                                paramTypes[parameterIndex] = isRestParameter_1 ? checker.createArrayType(type) : type;
                            }
                        }
                        return paramTypes;
                    }
                }
                return undefined;
            }
            InferFromReference.inferTypeForParametersFromReferences = inferTypeForParametersFromReferences;
            function inferTypeFromContext(node, checker, usageContext) {
                while (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
                    node = node.parent;
                }
                switch (node.parent.kind) {
                    case 193 /* PostfixUnaryExpression */:
                        usageContext.isNumber = true;
                        break;
                    case 192 /* PrefixUnaryExpression */:
                        inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext);
                        break;
                    case 194 /* BinaryExpression */:
                        inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext);
                        break;
                    case 257 /* CaseClause */:
                    case 258 /* DefaultClause */:
                        inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext);
                        break;
                    case 181 /* CallExpression */:
                    case 182 /* NewExpression */:
                        if (node.parent.expression === node) {
                            inferTypeFromCallExpressionContext(node.parent, checker, usageContext);
                        }
                        else {
                            inferTypeFromContextualType(node, checker, usageContext);
                        }
                        break;
                    case 179 /* PropertyAccessExpression */:
                        inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext);
                        break;
                    case 180 /* ElementAccessExpression */:
                        inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext);
                        break;
                    default:
                        return inferTypeFromContextualType(node, checker, usageContext);
                }
            }
            function inferTypeFromContextualType(node, checker, usageContext) {
                if (ts.isPartOfExpression(node)) {
                    addCandidateType(usageContext, checker.getContextualType(node));
                }
            }
            function inferTypeFromPrefixUnaryExpressionContext(node, usageContext) {
                switch (node.operator) {
                    case 43 /* PlusPlusToken */:
                    case 44 /* MinusMinusToken */:
                    case 38 /* MinusToken */:
                    case 52 /* TildeToken */:
                        usageContext.isNumber = true;
                        break;
                    case 37 /* PlusToken */:
                        usageContext.isNumberOrString = true;
                        break;
                }
            }
            function inferTypeFromBinaryExpressionContext(node, parent, checker, usageContext) {
                switch (parent.operatorToken.kind) {
                    // ExponentiationOperator
                    case 40 /* AsteriskAsteriskToken */:
                    // MultiplicativeOperator
                    case 39 /* AsteriskToken */:
                    case 41 /* SlashToken */:
                    case 42 /* PercentToken */:
                    // ShiftOperator
                    case 45 /* LessThanLessThanToken */:
                    case 46 /* GreaterThanGreaterThanToken */:
                    case 47 /* GreaterThanGreaterThanGreaterThanToken */:
                    // BitwiseOperator
                    case 48 /* AmpersandToken */:
                    case 49 /* BarToken */:
                    case 50 /* CaretToken */:
                    // CompoundAssignmentOperator
                    case 60 /* MinusEqualsToken */:
                    case 62 /* AsteriskAsteriskEqualsToken */:
                    case 61 /* AsteriskEqualsToken */:
                    case 63 /* SlashEqualsToken */:
                    case 64 /* PercentEqualsToken */:
                    case 68 /* AmpersandEqualsToken */:
                    case 69 /* BarEqualsToken */:
                    case 70 /* CaretEqualsToken */:
                    case 65 /* LessThanLessThanEqualsToken */:
                    case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 66 /* GreaterThanGreaterThanEqualsToken */:
                    // AdditiveOperator
                    case 38 /* MinusToken */:
                    // RelationalOperator
                    case 27 /* LessThanToken */:
                    case 30 /* LessThanEqualsToken */:
                    case 29 /* GreaterThanToken */:
                    case 31 /* GreaterThanEqualsToken */:
                        var operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
                        if (operandType.flags & 272 /* EnumLike */) {
                            addCandidateType(usageContext, operandType);
                        }
                        else {
                            usageContext.isNumber = true;
                        }
                        break;
                    case 59 /* PlusEqualsToken */:
                    case 37 /* PlusToken */:
                        var otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
                        if (otherOperandType.flags & 272 /* EnumLike */) {
                            addCandidateType(usageContext, otherOperandType);
                        }
                        else if (otherOperandType.flags & 84 /* NumberLike */) {
                            usageContext.isNumber = true;
                        }
                        else if (otherOperandType.flags & 262178 /* StringLike */) {
                            usageContext.isString = true;
                        }
                        else {
                            usageContext.isNumberOrString = true;
                        }
                        break;
                    //  AssignmentOperators
                    case 58 /* EqualsToken */:
                    case 32 /* EqualsEqualsToken */:
                    case 34 /* EqualsEqualsEqualsToken */:
                    case 35 /* ExclamationEqualsEqualsToken */:
                    case 33 /* ExclamationEqualsToken */:
                        addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left));
                        break;
                    case 92 /* InKeyword */:
                        if (node === parent.left) {
                            usageContext.isString = true;
                        }
                        break;
                    // LogicalOperator
                    case 54 /* BarBarToken */:
                        if (node === parent.left &&
                            (node.parent.parent.kind === 226 /* VariableDeclaration */ || ts.isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) {
                            // var x = x || {};
                            // TODO: use getFalsyflagsOfType
                            addCandidateType(usageContext, checker.getTypeAtLocation(parent.right));
                        }
                        break;
                    case 53 /* AmpersandAmpersandToken */:
                    case 26 /* CommaToken */:
                    case 93 /* InstanceOfKeyword */:
                        // nothing to infer here
                        break;
                }
            }
            function inferTypeFromSwitchStatementLabelContext(parent, checker, usageContext) {
                addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression));
            }
            function inferTypeFromCallExpressionContext(parent, checker, usageContext) {
                var callContext = {
                    argumentTypes: [],
                    returnType: {}
                };
                if (parent.arguments) {
                    for (var _i = 0, _a = parent.arguments; _i < _a.length; _i++) {
                        var argument = _a[_i];
                        callContext.argumentTypes.push(checker.getTypeAtLocation(argument));
                    }
                }
                inferTypeFromContext(parent, checker, callContext.returnType);
                if (parent.kind === 181 /* CallExpression */) {
                    (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext);
                }
                else {
                    (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext);
                }
            }
            function inferTypeFromPropertyAccessExpressionContext(parent, checker, usageContext) {
                var name = ts.escapeLeadingUnderscores(parent.name.text);
                if (!usageContext.properties) {
                    usageContext.properties = ts.createUnderscoreEscapedMap();
                }
                var propertyUsageContext = usageContext.properties.get(name) || {};
                inferTypeFromContext(parent, checker, propertyUsageContext);
                usageContext.properties.set(name, propertyUsageContext);
            }
            function inferTypeFromPropertyElementExpressionContext(parent, node, checker, usageContext) {
                if (node === parent.argumentExpression) {
                    usageContext.isNumberOrString = true;
                    return;
                }
                else {
                    var indexType = checker.getTypeAtLocation(parent);
                    var indexUsageContext = {};
                    inferTypeFromContext(parent, checker, indexUsageContext);
                    if (indexType.flags & 84 /* NumberLike */) {
                        usageContext.numberIndexContext = indexUsageContext;
                    }
                    else {
                        usageContext.stringIndexContext = indexUsageContext;
                    }
                }
            }
            function getTypeFromUsageContext(usageContext, checker) {
                if (usageContext.isNumberOrString && !usageContext.isNumber && !usageContext.isString) {
                    return checker.getUnionType([checker.getNumberType(), checker.getStringType()]);
                }
                else if (usageContext.isNumber) {
                    return checker.getNumberType();
                }
                else if (usageContext.isString) {
                    return checker.getStringType();
                }
                else if (usageContext.candidateTypes) {
                    return checker.getWidenedType(checker.getUnionType(ts.map(usageContext.candidateTypes, function (t) { return checker.getBaseTypeOfLiteralType(t); }), /*subtypeReduction*/ true));
                }
                else if (usageContext.properties && hasCallContext(usageContext.properties.get("then"))) {
                    var paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then").callContexts, /*isRestParameter*/ false, checker);
                    var types = paramType.getCallSignatures().map(function (c) { return c.getReturnType(); });
                    return checker.createPromiseType(types.length ? checker.getUnionType(types, /*subtypeReduction*/ true) : checker.getAnyType());
                }
                else if (usageContext.properties && hasCallContext(usageContext.properties.get("push"))) {
                    return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push").callContexts, /*isRestParameter*/ false, checker));
                }
                else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.numberIndexContext || usageContext.stringIndexContext) {
                    var members_4 = ts.createUnderscoreEscapedMap();
                    var callSignatures = [];
                    var constructSignatures = [];
                    var stringIndexInfo = void 0;
                    var numberIndexInfo = void 0;
                    if (usageContext.properties) {
                        usageContext.properties.forEach(function (context, name) {
                            var symbol = checker.createSymbol(4 /* Property */, name);
                            symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType();
                            members_4.set(name, symbol);
                        });
                    }
                    if (usageContext.callContexts) {
                        for (var _i = 0, _a = usageContext.callContexts; _i < _a.length; _i++) {
                            var callContext = _a[_i];
                            callSignatures.push(getSignatureFromCallContext(callContext, checker));
                        }
                    }
                    if (usageContext.constructContexts) {
                        for (var _b = 0, _c = usageContext.constructContexts; _b < _c.length; _b++) {
                            var constructContext = _c[_b];
                            constructSignatures.push(getSignatureFromCallContext(constructContext, checker));
                        }
                    }
                    if (usageContext.numberIndexContext) {
                        numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker), /*isReadonly*/ false);
                    }
                    if (usageContext.stringIndexContext) {
                        stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker), /*isReadonly*/ false);
                    }
                    return checker.createAnonymousType(/*symbol*/ undefined, members_4, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
                }
                else {
                    return undefined;
                }
            }
            function getParameterTypeFromCallContexts(parameterIndex, callContexts, isRestParameter, checker) {
                var types = [];
                if (callContexts) {
                    for (var _i = 0, callContexts_2 = callContexts; _i < callContexts_2.length; _i++) {
                        var callContext = callContexts_2[_i];
                        if (callContext.argumentTypes.length > parameterIndex) {
                            if (isRestParameter) {
                                types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); }));
                            }
                            else {
                                types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex]));
                            }
                        }
                    }
                }
                if (types.length) {
                    var type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true));
                    return isRestParameter ? checker.createArrayType(type) : type;
                }
                return undefined;
            }
            function getSignatureFromCallContext(callContext, checker) {
                var parameters = [];
                for (var i = 0; i < callContext.argumentTypes.length; i++) {
                    var symbol = checker.createSymbol(1 /* FunctionScopedVariable */, ts.escapeLeadingUnderscores("arg" + i));
                    symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i]));
                    parameters.push(symbol);
                }
                var returnType = getTypeFromUsageContext(callContext.returnType, checker) || checker.getVoidType();
                return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
            }
            function addCandidateType(context, type) {
                if (type && !(type.flags & 1 /* Any */) && !(type.flags & 8192 /* Never */)) {
                    (context.candidateTypes || (context.candidateTypes = [])).push(type);
                }
            }
            function hasCallContext(usageContext) {
                return usageContext && usageContext.callContexts;
            }
        })(InferFromReference || (InferFromReference = {}));
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/// <reference path="addMissingInvocationForDecorator.ts" />
/// <reference path="correctQualifiedNameToIndexedAccessType.ts" />
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
/// <reference path="fixAddMissingMember.ts" />
/// <reference path="fixSpelling.ts" />
/// <reference path="fixCannotFindModule.ts" />
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
/// <reference path="fixForgottenThisPropertyAccess.ts" />
/// <reference path='fixUnusedIdentifier.ts' />
/// <reference path='fixJSDocTypes.ts' />
/// <reference path='importFixes.ts' />
/// <reference path='disableJsDiagnostics.ts' />
/// <reference path='helpers.ts' />
/// <reference path='inferFromUsage.ts' />
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var annotateWithTypeFromJSDoc;
        (function (annotateWithTypeFromJSDoc) {
            var actionName = "annotate";
            var annotateTypeFromJSDoc = {
                name: "Annotate with type from JSDoc",
                description: ts.Diagnostics.Annotate_with_type_from_JSDoc.message,
                getEditsForAction: getEditsForAction,
                getAvailableActions: getAvailableActions
            };
            refactor.registerRefactor(annotateTypeFromJSDoc);
            function getAvailableActions(context) {
                if (ts.isInJavaScriptFile(context.file)) {
                    return undefined;
                }
                var node = ts.getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
                if (hasUsableJSDoc(ts.findAncestor(node, isDeclarationWithType))) {
                    return [{
                            name: annotateTypeFromJSDoc.name,
                            description: annotateTypeFromJSDoc.description,
                            actions: [
                                {
                                    description: annotateTypeFromJSDoc.description,
                                    name: actionName
                                }
                            ]
                        }];
                }
            }
            function hasUsableJSDoc(decl) {
                if (!decl) {
                    return false;
                }
                if (ts.isFunctionLikeDeclaration(decl)) {
                    return decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!ts.getJSDocReturnType(decl));
                }
                return !decl.type && !!ts.getJSDocType(decl);
            }
            function getEditsForAction(context, action) {
                if (actionName !== action) {
                    return ts.Debug.fail("actionName !== action: " + actionName + " !== " + action);
                }
                var node = ts.getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
                var decl = ts.findAncestor(node, isDeclarationWithType);
                if (!decl || decl.type) {
                    return undefined;
                }
                var jsdocType = ts.getJSDocType(decl);
                var isFunctionWithJSDoc = ts.isFunctionLikeDeclaration(decl) && (ts.getJSDocReturnType(decl) || decl.parameters.some(function (p) { return !!ts.getJSDocType(p); }));
                if (isFunctionWithJSDoc || jsdocType && decl.kind === 146 /* Parameter */) {
                    return getEditsForFunctionAnnotation(context);
                }
                else if (jsdocType) {
                    return getEditsForAnnotation(context);
                }
                else {
                    ts.Debug.assert(!!refactor, "No applicable refactor found.");
                }
            }
            function getEditsForAnnotation(context) {
                var sourceFile = context.file;
                var token = ts.getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
                var decl = ts.findAncestor(token, isDeclarationWithType);
                var jsdocType = ts.getJSDocType(decl);
                if (!decl || !jsdocType || decl.type) {
                    return ts.Debug.fail("!decl || !jsdocType || decl.type: !" + decl + " || !" + jsdocType + " || " + decl.type);
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var declarationWithType = addType(decl, transformJSDocType(jsdocType));
                ts.suppressLeadingAndTrailingTrivia(declarationWithType);
                changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, declarationWithType);
                return {
                    edits: changeTracker.getChanges(),
                    renameFilename: undefined,
                    renameLocation: undefined
                };
            }
            function getEditsForFunctionAnnotation(context) {
                var sourceFile = context.file;
                var token = ts.getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
                var decl = ts.findAncestor(token, ts.isFunctionLikeDeclaration);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var functionWithType = addTypesToFunctionLike(decl);
                ts.suppressLeadingAndTrailingTrivia(functionWithType);
                changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, functionWithType);
                return {
                    edits: changeTracker.getChanges(),
                    renameFilename: undefined,
                    renameLocation: undefined
                };
            }
            function isDeclarationWithType(node) {
                return ts.isFunctionLikeDeclaration(node) ||
                    node.kind === 226 /* VariableDeclaration */ ||
                    node.kind === 146 /* Parameter */ ||
                    node.kind === 148 /* PropertySignature */ ||
                    node.kind === 149 /* PropertyDeclaration */;
            }
            function addTypesToFunctionLike(decl) {
                var typeParameters = ts.getEffectiveTypeParameterDeclarations(decl, /*checkJSDoc*/ true);
                var parameters = decl.parameters.map(function (p) { return ts.createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, transformJSDocType(ts.getEffectiveTypeAnnotationNode(p, /*checkJSDoc*/ true)), p.initializer); });
                var returnType = transformJSDocType(ts.getEffectiveReturnTypeNode(decl, /*checkJSDoc*/ true));
                switch (decl.kind) {
                    case 228 /* FunctionDeclaration */:
                        return ts.createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body);
                    case 152 /* Constructor */:
                        return ts.createConstructor(decl.decorators, decl.modifiers, parameters, decl.body);
                    case 186 /* FunctionExpression */:
                        return ts.createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body);
                    case 187 /* ArrowFunction */:
                        return ts.createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body);
                    case 151 /* MethodDeclaration */:
                        return ts.createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, typeParameters, parameters, returnType, decl.body);
                    case 153 /* GetAccessor */:
                        return ts.createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, returnType, decl.body);
                    case 154 /* SetAccessor */:
                        return ts.createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body);
                    default:
                        return ts.Debug.assertNever(decl, "Unexpected SyntaxKind: " + decl.kind);
                }
            }
            function addType(decl, jsdocType) {
                switch (decl.kind) {
                    case 226 /* VariableDeclaration */:
                        return ts.createVariableDeclaration(decl.name, jsdocType, decl.initializer);
                    case 148 /* PropertySignature */:
                        return ts.createPropertySignature(decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer);
                    case 149 /* PropertyDeclaration */:
                        return ts.createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer);
                    default:
                        return ts.Debug.fail("Unexpected SyntaxKind: " + decl.kind);
                }
            }
            function transformJSDocType(node) {
                if (node === undefined) {
                    return undefined;
                }
                switch (node.kind) {
                    case 268 /* JSDocAllType */:
                    case 269 /* JSDocUnknownType */:
                        return ts.createTypeReferenceNode("any", ts.emptyArray);
                    case 272 /* JSDocOptionalType */:
                        return transformJSDocOptionalType(node);
                    case 271 /* JSDocNonNullableType */:
                        return transformJSDocType(node.type);
                    case 270 /* JSDocNullableType */:
                        return transformJSDocNullableType(node);
                    case 274 /* JSDocVariadicType */:
                        return transformJSDocVariadicType(node);
                    case 273 /* JSDocFunctionType */:
                        return transformJSDocFunctionType(node);
                    case 146 /* Parameter */:
                        return transformJSDocParameter(node);
                    case 159 /* TypeReference */:
                        return transformJSDocTypeReference(node);
                    default:
                        var visited = ts.visitEachChild(node, transformJSDocType, /*context*/ undefined);
                        ts.setEmitFlags(visited, 1 /* SingleLine */);
                        return visited;
                }
            }
            function transformJSDocOptionalType(node) {
                return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("undefined", ts.emptyArray)]);
            }
            function transformJSDocNullableType(node) {
                return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("null", ts.emptyArray)]);
            }
            function transformJSDocVariadicType(node) {
                return ts.createArrayTypeNode(ts.visitNode(node.type, transformJSDocType));
            }
            function transformJSDocFunctionType(node) {
                var parameters = node.parameters && node.parameters.map(transformJSDocType);
                return ts.createFunctionTypeNode(ts.emptyArray, parameters, node.type);
            }
            function transformJSDocParameter(node) {
                var index = node.parent.parameters.indexOf(node);
                var isRest = node.type.kind === 274 /* JSDocVariadicType */ && index === node.parent.parameters.length - 1;
                var name = node.name || (isRest ? "rest" : "arg" + index);
                var dotdotdot = isRest ? ts.createToken(24 /* DotDotDotToken */) : node.dotDotDotToken;
                return ts.createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, ts.visitNode(node.type, transformJSDocType), node.initializer);
            }
            function transformJSDocTypeReference(node) {
                var name = node.typeName;
                var args = node.typeArguments;
                if (ts.isIdentifier(node.typeName)) {
                    if (ts.isJSDocIndexSignature(node)) {
                        return transformJSDocIndexSignature(node);
                    }
                    var text = node.typeName.text;
                    switch (node.typeName.text) {
                        case "String":
                        case "Boolean":
                        case "Object":
                        case "Number":
                            text = text.toLowerCase();
                            break;
                        case "array":
                        case "date":
                        case "promise":
                            text = text[0].toUpperCase() + text.slice(1);
                            break;
                    }
                    name = ts.createIdentifier(text);
                    if ((text === "Array" || text === "Promise") && !node.typeArguments) {
                        args = ts.createNodeArray([ts.createTypeReferenceNode("any", ts.emptyArray)]);
                    }
                    else {
                        args = ts.visitNodes(node.typeArguments, transformJSDocType);
                    }
                }
                return ts.createTypeReferenceNode(name, args);
            }
            function transformJSDocIndexSignature(node) {
                var index = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, node.typeArguments[0].kind === 133 /* NumberKeyword */ ? "n" : "s", 
                /*questionToken*/ undefined, ts.createTypeReferenceNode(node.typeArguments[0].kind === 133 /* NumberKeyword */ ? "number" : "string", []), 
                /*initializer*/ undefined);
                var indexSignature = ts.createTypeLiteralNode([ts.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments[1])]);
                ts.setEmitFlags(indexSignature, 1 /* SingleLine */);
                return indexSignature;
            }
        })(annotateWithTypeFromJSDoc = refactor.annotateWithTypeFromJSDoc || (refactor.annotateWithTypeFromJSDoc = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var convertFunctionToES6Class;
        (function (convertFunctionToES6Class_1) {
            var actionName = "convert";
            var convertFunctionToES6Class = {
                name: "Convert to ES2015 class",
                description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message,
                getEditsForAction: getEditsForAction,
                getAvailableActions: getAvailableActions
            };
            refactor.registerRefactor(convertFunctionToES6Class);
            function getAvailableActions(context) {
                if (!ts.isInJavaScriptFile(context.file)) {
                    return undefined;
                }
                var symbol = getConstructorSymbol(context);
                if (!symbol) {
                    return undefined;
                }
                if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) {
                    symbol = symbol.valueDeclaration.initializer.symbol;
                }
                if ((symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) {
                    return [
                        {
                            name: convertFunctionToES6Class.name,
                            description: convertFunctionToES6Class.description,
                            actions: [
                                {
                                    description: convertFunctionToES6Class.description,
                                    name: actionName
                                }
                            ]
                        }
                    ];
                }
            }
            function getEditsForAction(context, action) {
                // Somehow wrong action got invoked?
                if (actionName !== action) {
                    return undefined;
                }
                var sourceFile = context.file;
                var ctorSymbol = getConstructorSymbol(context);
                var newLine = context.rulesProvider.getFormatOptions().newLineCharacter;
                var deletedNodes = [];
                var deletes = [];
                if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) {
                    return undefined;
                }
                var ctorDeclaration = ctorSymbol.valueDeclaration;
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var precedingNode;
                var newClassDeclaration;
                switch (ctorDeclaration.kind) {
                    case 228 /* FunctionDeclaration */:
                        precedingNode = ctorDeclaration;
                        deleteNode(ctorDeclaration);
                        newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration);
                        break;
                    case 226 /* VariableDeclaration */:
                        precedingNode = ctorDeclaration.parent.parent;
                        if (ctorDeclaration.parent.declarations.length === 1) {
                            deleteNode(precedingNode);
                        }
                        else {
                            deleteNode(ctorDeclaration, /*inList*/ true);
                        }
                        newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration);
                        break;
                }
                if (!newClassDeclaration) {
                    return undefined;
                }
                // Because the preceding node could be touched, we need to insert nodes before delete nodes.
                changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine });
                for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) {
                    var deleteCallback = deletes_1[_i];
                    deleteCallback();
                }
                return {
                    edits: changeTracker.getChanges(),
                    renameFilename: undefined,
                    renameLocation: undefined,
                };
                function deleteNode(node, inList) {
                    if (inList === void 0) { inList = false; }
                    if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) {
                        // Parent node has already been deleted; do nothing
                        return;
                    }
                    deletedNodes.push(node);
                    if (inList) {
                        deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); });
                    }
                    else {
                        deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); });
                    }
                }
                function createClassElementsFromSymbol(symbol) {
                    var memberElements = [];
                    // all instance members are stored in the "member" array of symbol
                    if (symbol.members) {
                        symbol.members.forEach(function (member) {
                            var memberElement = createClassElement(member, /*modifiers*/ undefined);
                            if (memberElement) {
                                memberElements.push(memberElement);
                            }
                        });
                    }
                    // all static members are stored in the "exports" array of symbol
                    if (symbol.exports) {
                        symbol.exports.forEach(function (member) {
                            var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]);
                            if (memberElement) {
                                memberElements.push(memberElement);
                            }
                        });
                    }
                    return memberElements;
                    function shouldConvertDeclaration(_target, source) {
                        // Right now the only thing we can convert are function expressions - other values shouldn't get
                        // transformed. We can update this once ES public class properties are available.
                        return ts.isFunctionLike(source);
                    }
                    function createClassElement(symbol, modifiers) {
                        // both properties and methods are bound as property symbols
                        if (!(symbol.flags & 4 /* Property */)) {
                            return;
                        }
                        var memberDeclaration = symbol.valueDeclaration;
                        var assignmentBinaryExpression = memberDeclaration.parent;
                        if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) {
                            return;
                        }
                        // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end
                        var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 /* ExpressionStatement */
                            ? assignmentBinaryExpression.parent : assignmentBinaryExpression;
                        deleteNode(nodeToDelete);
                        if (!assignmentBinaryExpression.right) {
                            return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, 
                            /*type*/ undefined, /*initializer*/ undefined);
                        }
                        switch (assignmentBinaryExpression.right.kind) {
                            case 186 /* FunctionExpression */: {
                                var functionExpression = assignmentBinaryExpression.right;
                                var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(functionExpression, 120 /* AsyncKeyword */));
                                var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
                                /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body);
                                copyComments(assignmentBinaryExpression, method);
                                return method;
                            }
                            case 187 /* ArrowFunction */: {
                                var arrowFunction = assignmentBinaryExpression.right;
                                var arrowFunctionBody = arrowFunction.body;
                                var bodyBlock = void 0;
                                // case 1: () => { return [1,2,3] }
                                if (arrowFunctionBody.kind === 207 /* Block */) {
                                    bodyBlock = arrowFunctionBody;
                                }
                                else {
                                    var expression = arrowFunctionBody;
                                    bodyBlock = ts.createBlock([ts.createReturn(expression)]);
                                }
                                var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(arrowFunction, 120 /* AsyncKeyword */));
                                var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
                                /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock);
                                copyComments(assignmentBinaryExpression, method);
                                return method;
                            }
                            default: {
                                // Don't try to declare members in JavaScript files
                                if (ts.isSourceFileJavaScript(sourceFile)) {
                                    return;
                                }
                                var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, 
                                /*type*/ undefined, assignmentBinaryExpression.right);
                                copyComments(assignmentBinaryExpression.parent, prop);
                                return prop;
                            }
                        }
                    }
                }
                function copyComments(sourceNode, targetNode) {
                    ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) {
                        if (kind === 3 /* MultiLineCommentTrivia */) {
                            // Remove leading /*
                            pos += 2;
                            // Remove trailing */
                            end -= 2;
                        }
                        else {
                            // Remove leading //
                            pos += 2;
                        }
                        ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl);
                    });
                }
                function createClassFromVariableDeclaration(node) {
                    var initializer = node.initializer;
                    if (!initializer || initializer.kind !== 186 /* FunctionExpression */) {
                        return undefined;
                    }
                    if (node.name.kind !== 71 /* Identifier */) {
                        return undefined;
                    }
                    var memberElements = createClassElementsFromSymbol(initializer.symbol);
                    if (initializer.body) {
                        memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body));
                    }
                    var modifiers = getModifierKindFromSource(precedingNode, 84 /* ExportKeyword */);
                    var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
                    /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
                    // Don't call copyComments here because we'll already leave them in place
                    return cls;
                }
                function createClassFromFunctionDeclaration(node) {
                    var memberElements = createClassElementsFromSymbol(ctorSymbol);
                    if (node.body) {
                        memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body));
                    }
                    var modifiers = getModifierKindFromSource(node, 84 /* ExportKeyword */);
                    var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
                    /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
                    // Don't call copyComments here because we'll already leave them in place
                    return cls;
                }
                function getModifierKindFromSource(source, kind) {
                    return ts.filter(source.modifiers, function (modifier) { return modifier.kind === kind; });
                }
            }
            function getConstructorSymbol(_a) {
                var startPosition = _a.startPosition, file = _a.file, program = _a.program;
                var checker = program.getTypeChecker();
                var token = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
                return checker.getSymbolAtLocation(token);
            }
        })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/// <reference path="../refactorProvider.ts" />
/// <reference path="../../compiler/checker.ts" />
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var extractSymbol;
        (function (extractSymbol_1) {
            var extractSymbol = {
                name: "Extract Symbol",
                description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_symbol),
                getAvailableActions: getAvailableActions,
                getEditsForAction: getEditsForAction,
            };
            refactor.registerRefactor(extractSymbol);
            /**
             * Compute the associated code actions
             * Exported for tests.
             */
            function getAvailableActions(context) {
                var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: ts.getRefactorContextLength(context) });
                var targetRange = rangeToExtract.targetRange;
                if (targetRange === undefined) {
                    return undefined;
                }
                var extractions = getPossibleExtractions(targetRange, context);
                if (extractions === undefined) {
                    // No extractions possible
                    return undefined;
                }
                var functionActions = [];
                var usedFunctionNames = ts.createMap();
                var constantActions = [];
                var usedConstantNames = ts.createMap();
                var i = 0;
                for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) {
                    var _a = extractions_1[_i], functionExtraction = _a.functionExtraction, constantExtraction = _a.constantExtraction;
                    // Skip these since we don't have a way to report errors yet
                    if (functionExtraction.errors.length === 0) {
                        // Don't issue refactorings with duplicated names.
                        // Scopes come back in "innermost first" order, so extractions will
                        // preferentially go into nearer scopes
                        var description = functionExtraction.description;
                        if (!usedFunctionNames.has(description)) {
                            usedFunctionNames.set(description, true);
                            functionActions.push({
                                description: description,
                                name: "function_scope_" + i
                            });
                        }
                    }
                    // Skip these since we don't have a way to report errors yet
                    if (constantExtraction.errors.length === 0) {
                        // Don't issue refactorings with duplicated names.
                        // Scopes come back in "innermost first" order, so extractions will
                        // preferentially go into nearer scopes
                        var description = constantExtraction.description;
                        if (!usedConstantNames.has(description)) {
                            usedConstantNames.set(description, true);
                            constantActions.push({
                                description: description,
                                name: "constant_scope_" + i
                            });
                        }
                    }
                    // *do* increment i anyway because we'll look for the i-th scope
                    // later when actually doing the refactoring if the user requests it
                    i++;
                }
                var infos = [];
                if (functionActions.length) {
                    infos.push({
                        name: extractSymbol.name,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function),
                        actions: functionActions
                    });
                }
                if (constantActions.length) {
                    infos.push({
                        name: extractSymbol.name,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant),
                        actions: constantActions
                    });
                }
                return infos.length ? infos : undefined;
            }
            extractSymbol_1.getAvailableActions = getAvailableActions;
            /* Exported for tests */
            function getEditsForAction(context, actionName) {
                var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: ts.getRefactorContextLength(context) });
                var targetRange = rangeToExtract.targetRange;
                var parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName);
                if (parsedFunctionIndexMatch) {
                    var index = +parsedFunctionIndexMatch[1];
                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index");
                    return getFunctionExtractionAtIndex(targetRange, context, index);
                }
                var parsedConstantIndexMatch = /^constant_scope_(\d+)$/.exec(actionName);
                if (parsedConstantIndexMatch) {
                    var index = +parsedConstantIndexMatch[1];
                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index");
                    return getConstantExtractionAtIndex(targetRange, context, index);
                }
                ts.Debug.fail("Unrecognized action name");
            }
            extractSymbol_1.getEditsForAction = getEditsForAction;
            // Move these into diagnostic messages if they become user-facing
            var Messages;
            (function (Messages) {
                function createMessage(message) {
                    return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message };
                }
                Messages.CannotExtractRange = createMessage("Cannot extract range.");
                Messages.CannotExtractImport = createMessage("Cannot extract import statement.");
                Messages.CannotExtractSuper = createMessage("Cannot extract super call.");
                Messages.CannotExtractEmpty = createMessage("Cannot extract empty range.");
                Messages.ExpressionExpected = createMessage("expression expected.");
                Messages.UselessConstantType = createMessage("No reason to extract constant of type.");
                Messages.StatementOrExpressionExpected = createMessage("Statement or expression expected.");
                Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements.");
                Messages.CannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement.");
                Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range.");
                Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators.");
                Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope.");
                Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope.");
                Messages.CannotExtractIdentifier = createMessage("Select more than a single identifier.");
                Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration");
                Messages.CannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression");
                Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor");
                Messages.CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts");
                Messages.CannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes");
                Messages.CannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function");
                Messages.CannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS");
                Messages.CannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block");
            })(Messages = extractSymbol_1.Messages || (extractSymbol_1.Messages = {}));
            var RangeFacts;
            (function (RangeFacts) {
                RangeFacts[RangeFacts["None"] = 0] = "None";
                RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn";
                RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator";
                RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction";
                RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis";
                /**
                 * The range is in a function which needs the 'static' modifier in a class
                 */
                RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion";
            })(RangeFacts || (RangeFacts = {}));
            /**
             * getRangeToExtract takes a span inside a text file and returns either an expression or an array
             * of statements representing the minimum set of nodes needed to extract the entire span. This
             * process may fail, in which case a set of errors is returned instead (these are currently
             * not shown to the user, but can be used by us diagnostically)
             */
            // exported only for tests
            function getRangeToExtract(sourceFile, span) {
                var length = span.length;
                if (length === 0) {
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractEmpty)] };
                }
                // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
                // This may fail (e.g. you select two statements in the root of a source file)
                var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
                // Do the same for the ending position
                var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span);
                var declarations = [];
                // We'll modify these flags as we walk the tree to collect data
                // about what things need to be done as part of the extraction.
                var rangeFacts = RangeFacts.None;
                if (!start || !end) {
                    // cannot find either start or end node
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
                }
                if (start.parent !== end.parent) {
                    // start and end nodes belong to different subtrees
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
                }
                if (start !== end) {
                    // start and end should be statements and parent should be either block or a source file
                    if (!isBlockLike(start.parent)) {
                        return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
                    }
                    var statements = [];
                    for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) {
                        var statement = _a[_i];
                        if (statement === start || statements.length) {
                            var errors_1 = checkNode(statement);
                            if (errors_1) {
                                return { errors: errors_1 };
                            }
                            statements.push(statement);
                        }
                        if (statement === end) {
                            break;
                        }
                    }
                    return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } };
                }
                // We have a single node (start)
                var errors = checkRootNode(start) || checkNode(start);
                if (errors) {
                    return { errors: errors };
                }
                return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } };
                function checkRootNode(node) {
                    if (ts.isIdentifier(ts.isExpressionStatement(node) ? node.expression : node)) {
                        return [ts.createDiagnosticForNode(node, Messages.CannotExtractIdentifier)];
                    }
                    return undefined;
                }
                function checkForStaticContext(nodeToCheck, containingClass) {
                    var current = nodeToCheck;
                    while (current !== containingClass) {
                        if (current.kind === 149 /* PropertyDeclaration */) {
                            if (ts.hasModifier(current, 32 /* Static */)) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                            break;
                        }
                        else if (current.kind === 146 /* Parameter */) {
                            var ctorOrMethod = ts.getContainingFunction(current);
                            if (ctorOrMethod.kind === 152 /* Constructor */) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                            break;
                        }
                        else if (current.kind === 151 /* MethodDeclaration */) {
                            if (ts.hasModifier(current, 32 /* Static */)) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                        }
                        current = current.parent;
                    }
                }
                // Verifies whether we can actually extract this node or not.
                function checkNode(nodeToCheck) {
                    var PermittedJumps;
                    (function (PermittedJumps) {
                        PermittedJumps[PermittedJumps["None"] = 0] = "None";
                        PermittedJumps[PermittedJumps["Break"] = 1] = "Break";
                        PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue";
                        PermittedJumps[PermittedJumps["Return"] = 4] = "Return";
                    })(PermittedJumps || (PermittedJumps = {}));
                    if (!ts.isStatement(nodeToCheck) && !(ts.isPartOfExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
                    }
                    if (ts.isInAmbientContext(nodeToCheck)) {
                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)];
                    }
                    // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default)
                    var containingClass = ts.getContainingClass(nodeToCheck);
                    if (containingClass) {
                        checkForStaticContext(nodeToCheck, containingClass);
                    }
                    var errors;
                    var permittedJumps = 4 /* Return */;
                    var seenLabels;
                    visit(nodeToCheck);
                    return errors;
                    function visit(node) {
                        if (errors) {
                            // already found an error - can stop now
                            return true;
                        }
                        if (ts.isDeclaration(node)) {
                            var declaringNode = (node.kind === 226 /* VariableDeclaration */) ? node.parent.parent : node;
                            if (ts.hasModifier(declaringNode, 1 /* Export */)) {
                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity));
                                return true;
                            }
                            declarations.push(node.symbol);
                        }
                        // Some things can't be extracted in certain situations
                        switch (node.kind) {
                            case 238 /* ImportDeclaration */:
                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractImport));
                                return true;
                            case 97 /* SuperKeyword */:
                                // For a super *constructor call*, we have to be extracting the entire class,
                                // but a super *method call* simply implies a 'this' reference
                                if (node.parent.kind === 181 /* CallExpression */) {
                                    // Super constructor call
                                    var containingClass_1 = ts.getContainingClass(node);
                                    if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) {
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractSuper));
                                        return true;
                                    }
                                }
                                else {
                                    rangeFacts |= RangeFacts.UsesThis;
                                }
                                break;
                        }
                        if (!node || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node)) {
                            switch (node.kind) {
                                case 228 /* FunctionDeclaration */:
                                case 229 /* ClassDeclaration */:
                                    if (node.parent.kind === 265 /* SourceFile */ && node.parent.externalModuleIndicator === undefined) {
                                        // You cannot extract global declarations
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope));
                                    }
                                    break;
                            }
                            // do not dive into functions or classes
                            return false;
                        }
                        var savedPermittedJumps = permittedJumps;
                        switch (node.kind) {
                            case 211 /* IfStatement */:
                                permittedJumps = 0 /* None */;
                                break;
                            case 224 /* TryStatement */:
                                // forbid all jumps inside try blocks
                                permittedJumps = 0 /* None */;
                                break;
                            case 207 /* Block */:
                                if (node.parent && node.parent.kind === 224 /* TryStatement */ && node.parent.finallyBlock === node) {
                                    // allow unconditional returns from finally blocks
                                    permittedJumps = 4 /* Return */;
                                }
                                break;
                            case 257 /* CaseClause */:
                                // allow unlabeled break inside case clauses
                                permittedJumps |= 1 /* Break */;
                                break;
                            default:
                                if (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false)) {
                                    // allow unlabeled break/continue inside loops
                                    permittedJumps |= 1 /* Break */ | 2 /* Continue */;
                                }
                                break;
                        }
                        switch (node.kind) {
                            case 169 /* ThisType */:
                            case 99 /* ThisKeyword */:
                                rangeFacts |= RangeFacts.UsesThis;
                                break;
                            case 222 /* LabeledStatement */:
                                {
                                    var label = node.label;
                                    (seenLabels || (seenLabels = [])).push(label.escapedText);
                                    ts.forEachChild(node, visit);
                                    seenLabels.pop();
                                    break;
                                }
                            case 218 /* BreakStatement */:
                            case 217 /* ContinueStatement */:
                                {
                                    var label = node.label;
                                    if (label) {
                                        if (!ts.contains(seenLabels, label.escapedText)) {
                                            // attempts to jump to label that is not in range to be extracted
                                            (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange));
                                        }
                                    }
                                    else {
                                        if (!(permittedJumps & (node.kind === 218 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) {
                                            // attempt to break or continue in a forbidden context
                                            (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements));
                                        }
                                    }
                                    break;
                                }
                            case 191 /* AwaitExpression */:
                                rangeFacts |= RangeFacts.IsAsyncFunction;
                                break;
                            case 197 /* YieldExpression */:
                                rangeFacts |= RangeFacts.IsGenerator;
                                break;
                            case 219 /* ReturnStatement */:
                                if (permittedJumps & 4 /* Return */) {
                                    rangeFacts |= RangeFacts.HasReturn;
                                }
                                else {
                                    (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement));
                                }
                                break;
                            default:
                                ts.forEachChild(node, visit);
                                break;
                        }
                        permittedJumps = savedPermittedJumps;
                    }
                }
            }
            extractSymbol_1.getRangeToExtract = getRangeToExtract;
            function getStatementOrExpressionRange(node) {
                if (ts.isStatement(node)) {
                    return [node];
                }
                else if (ts.isPartOfExpression(node)) {
                    // If our selection is the expression in an ExpressionStatement, expand
                    // the selection to include the enclosing Statement (this stops us
                    // from trying to care about the return value of the extracted function
                    // and eliminates double semicolon insertion in certain scenarios)
                    return ts.isExpressionStatement(node.parent) ? [node.parent] : node;
                }
                return undefined;
            }
            function isScope(node) {
                return ts.isFunctionLikeDeclaration(node) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node);
            }
            /**
             * Computes possible places we could extract the function into. For example,
             * you may be able to extract into a class method *or* local closure *or* namespace function,
             * depending on what's in the extracted body.
             */
            function collectEnclosingScopes(range) {
                var current = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
                if (range.facts & RangeFacts.UsesThis) {
                    // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class
                    var containingClass = ts.getContainingClass(current);
                    if (containingClass) {
                        var containingFunction = ts.findAncestor(current, ts.isFunctionLikeDeclaration);
                        return containingFunction
                            ? [containingFunction, containingClass]
                            : [containingClass];
                    }
                }
                var scopes = [];
                while (true) {
                    current = current.parent;
                    // A function parameter's initializer is actually in the outer scope, not the function declaration
                    if (current.kind === 146 /* Parameter */) {
                        // Skip all the way to the outer scope of the function that declared this parameter
                        current = ts.findAncestor(current, function (parent) { return ts.isFunctionLikeDeclaration(parent); }).parent;
                    }
                    // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of.
                    // Walk up to the closest parent of a place where we can logically put a sibling:
                    //  * Function declaration
                    //  * Class declaration or expression
                    //  * Module/namespace or source file
                    if (isScope(current)) {
                        scopes.push(current);
                        if (current.kind === 265 /* SourceFile */) {
                            return scopes;
                        }
                    }
                }
            }
            function getFunctionExtractionAtIndex(targetRange, context, requestedChangesIndex) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, functionErrorsPerScope = _b.functionErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
                ts.Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
                context.cancellationToken.throwIfCancellationRequested();
                return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context);
            }
            function getConstantExtractionAtIndex(targetRange, context, requestedChangesIndex) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, constantErrorsPerScope = _b.constantErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
                ts.Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
                ts.Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?");
                context.cancellationToken.throwIfCancellationRequested();
                var expression = ts.isExpression(target)
                    ? target
                    : target.statements[0].expression;
                return extractConstantInScope(expression, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange.facts, context);
            }
            /**
             * Given a piece of text to extract ('targetRange'), computes a list of possible extractions.
             * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes
             * or an error explaining why we can't extract into that scope.
             */
            function getPossibleExtractions(targetRange, context) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, functionErrorsPerScope = _b.functionErrorsPerScope, constantErrorsPerScope = _b.constantErrorsPerScope;
                // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547
                var extractions = scopes.map(function (scope, i) {
                    var functionDescriptionPart = getDescriptionForFunctionInScope(scope);
                    var constantDescriptionPart = getDescriptionForConstantInScope(scope);
                    var scopeDescription = ts.isFunctionLikeDeclaration(scope)
                        ? getDescriptionForFunctionLikeDeclaration(scope)
                        : ts.isClassLike(scope)
                            ? getDescriptionForClassLikeDeclaration(scope)
                            : getDescriptionForModuleLikeDeclaration(scope);
                    var functionDescription;
                    var constantDescription;
                    if (scopeDescription === 1 /* Global */) {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]);
                    }
                    else if (scopeDescription === 0 /* Module */) {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]);
                    }
                    else {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]);
                    }
                    // Customize the phrasing for the innermost scope to increase clarity.
                    if (i === 0 && !ts.isClassLike(scope)) {
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]);
                    }
                    return {
                        functionExtraction: {
                            description: functionDescription,
                            errors: functionErrorsPerScope[i],
                        },
                        constantExtraction: {
                            description: constantDescription,
                            errors: constantErrorsPerScope[i],
                        },
                    };
                });
                return extractions;
            }
            function getPossibleExtractionsWorker(targetRange, context) {
                var sourceFile = context.file;
                var scopes = collectEnclosingScopes(targetRange);
                var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile);
                var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker(), context.cancellationToken);
                return { scopes: scopes, readsAndWrites: readsAndWrites };
            }
            function getDescriptionForFunctionInScope(scope) {
                return ts.isFunctionLikeDeclaration(scope)
                    ? "inner function"
                    : ts.isClassLike(scope)
                        ? "method"
                        : "function";
            }
            function getDescriptionForConstantInScope(scope) {
                return ts.isClassLike(scope)
                    ? "readonly field"
                    : "constant";
            }
            function getDescriptionForFunctionLikeDeclaration(scope) {
                switch (scope.kind) {
                    case 152 /* Constructor */:
                        return "constructor";
                    case 186 /* FunctionExpression */:
                        return scope.name
                            ? "function expression '" + scope.name.text + "'"
                            : "anonymous function expression";
                    case 228 /* FunctionDeclaration */:
                        return "function '" + scope.name.text + "'";
                    case 187 /* ArrowFunction */:
                        return "arrow function";
                    case 151 /* MethodDeclaration */:
                        return "method '" + scope.name.getText();
                    case 153 /* GetAccessor */:
                        return "'get " + scope.name.getText() + "'";
                    case 154 /* SetAccessor */:
                        return "'set " + scope.name.getText() + "'";
                    default:
                        ts.Debug.assertNever(scope);
                }
            }
            function getDescriptionForClassLikeDeclaration(scope) {
                return scope.kind === 229 /* ClassDeclaration */
                    ? "class '" + scope.name.text + "'"
                    : scope.name ? "class expression '" + scope.name.text + "'" : "anonymous class expression";
            }
            function getDescriptionForModuleLikeDeclaration(scope) {
                return scope.kind === 234 /* ModuleBlock */
                    ? "namespace '" + scope.parent.name.getText() + "'"
                    : scope.externalModuleIndicator ? 0 /* Module */ : 1 /* Global */;
            }
            var SpecialScope;
            (function (SpecialScope) {
                SpecialScope[SpecialScope["Module"] = 0] = "Module";
                SpecialScope[SpecialScope["Global"] = 1] = "Global";
            })(SpecialScope || (SpecialScope = {}));
            function getUniqueName(baseName, fileText) {
                var nameText = baseName;
                for (var i = 1; ts.stringContains(fileText, nameText); i++) {
                    nameText = baseName + "_" + i;
                }
                return nameText;
            }
            /**
             * Result of 'extractRange' operation for a specific scope.
             * Stores either a list of changes that should be applied to extract a range or a list of errors
             */
            function extractFunctionInScope(node, scope, _a, exposedVariableDeclarations, range, context) {
                var usagesInScope = _a.usages, typeParameterUsages = _a.typeParameterUsages, substitutions = _a.substitutions;
                var checker = context.program.getTypeChecker();
                // Make a unique name for the extracted function
                var file = scope.getSourceFile();
                var functionNameText = getUniqueName(ts.isClassLike(scope) ? "newMethod" : "newFunction", file.text);
                var isJS = ts.isInJavaScriptFile(scope);
                var functionName = ts.createIdentifier(functionNameText);
                var returnType = undefined;
                var parameters = [];
                var callArguments = [];
                var writes;
                usagesInScope.forEach(function (usage, name) {
                    var typeNode = undefined;
                    if (!isJS) {
                        var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node);
                        // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
                        type = checker.getBaseTypeOfLiteralType(type);
                        typeNode = checker.typeToTypeNode(type, node, ts.NodeBuilderFlags.NoTruncation);
                    }
                    var paramDecl = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, 
                    /*name*/ name, 
                    /*questionToken*/ undefined, typeNode);
                    parameters.push(paramDecl);
                    if (usage.usage === 2 /* Write */) {
                        (writes || (writes = [])).push(usage);
                    }
                    callArguments.push(ts.createIdentifier(name));
                });
                var typeParametersAndDeclarations = ts.arrayFrom(typeParameterUsages.values()).map(function (type) { return ({ type: type, declaration: getFirstDeclaration(type) }); });
                var sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
                var typeParameters = sortedTypeParametersAndDeclarations.length === 0
                    ? undefined
                    : sortedTypeParametersAndDeclarations.map(function (t) { return t.declaration; });
                // Strictly speaking, we should check whether each name actually binds to the appropriate type
                // parameter.  In cases of shadowing, they may not.
                var callTypeArguments = typeParameters !== undefined
                    ? typeParameters.map(function (decl) { return ts.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined); })
                    : undefined;
                // Provide explicit return types for contextually-typed functions
                // to avoid problems when there are literal types present
                if (ts.isExpression(node) && !isJS) {
                    var contextualType = checker.getContextualType(node);
                    returnType = checker.typeToTypeNode(contextualType, scope, ts.NodeBuilderFlags.NoTruncation);
                }
                var _b = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty;
                ts.suppressLeadingAndTrailingTrivia(body);
                var newFunction;
                if (ts.isClassLike(scope)) {
                    // always create private method in TypeScript files
                    var modifiers = isJS ? [] : [ts.createToken(112 /* PrivateKeyword */)];
                    if (range.facts & RangeFacts.InStaticRegion) {
                        modifiers.push(ts.createToken(115 /* StaticKeyword */));
                    }
                    if (range.facts & RangeFacts.IsAsyncFunction) {
                        modifiers.push(ts.createToken(120 /* AsyncKeyword */));
                    }
                    newFunction = ts.createMethod(
                    /*decorators*/ undefined, modifiers.length ? modifiers : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, 
                    /*questionToken*/ undefined, typeParameters, parameters, returnType, body);
                }
                else {
                    newFunction = ts.createFunctionDeclaration(
                    /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, typeParameters, parameters, returnType, body);
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var minInsertionPos = (isReadonlyArray(range.range) ? ts.last(range.range) : range.range).end;
                var nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope);
                if (nodeToInsertBefore) {
                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, { suffix: context.newLineCharacter + context.newLineCharacter });
                }
                else {
                    changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, {
                        prefix: ts.isLineBreak(file.text.charCodeAt(scope.getLastToken().pos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter,
                        suffix: context.newLineCharacter
                    });
                }
                var newNodes = [];
                // replace range with function call
                var called = getCalledExpression(scope, range, functionNameText);
                var call = ts.createCall(called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference
                callArguments);
                if (range.facts & RangeFacts.IsGenerator) {
                    call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call);
                }
                if (range.facts & RangeFacts.IsAsyncFunction) {
                    call = ts.createAwait(call);
                }
                if (exposedVariableDeclarations.length && !writes) {
                    // No need to mix declarations and writes.
                    // How could any variables be exposed if there's a return statement?
                    ts.Debug.assert(!returnValueProperty);
                    ts.Debug.assert(!(range.facts & RangeFacts.HasReturn));
                    if (exposedVariableDeclarations.length === 1) {
                        // Declaring exactly one variable: let x = newFunction();
                        var variableDeclaration = exposedVariableDeclarations[0];
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepClone(variableDeclaration.name), /*type*/ ts.getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns
                        variableDeclaration.parent.flags)));
                    }
                    else {
                        // Declaring multiple variables / return properties:
                        //   let {x, y} = newFunction();
                        var bindingElements = [];
                        var typeElements = [];
                        var commonNodeFlags = exposedVariableDeclarations[0].parent.flags;
                        var sawExplicitType = false;
                        for (var _i = 0, exposedVariableDeclarations_1 = exposedVariableDeclarations; _i < exposedVariableDeclarations_1.length; _i++) {
                            var variableDeclaration = exposedVariableDeclarations_1[_i];
                            bindingElements.push(ts.createBindingElement(
                            /*dotDotDotToken*/ undefined, 
                            /*propertyName*/ undefined, 
                            /*name*/ ts.getSynthesizedDeepClone(variableDeclaration.name)));
                            // Being returned through an object literal will have widened the type.
                            var variableType = checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, ts.NodeBuilderFlags.NoTruncation);
                            typeElements.push(ts.createPropertySignature(
                            /*modifiers*/ undefined, 
                            /*name*/ variableDeclaration.symbol.name, 
                            /*questionToken*/ undefined, 
                            /*type*/ variableType, 
                            /*initializer*/ undefined));
                            sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined;
                            commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags;
                        }
                        var typeLiteral = sawExplicitType ? ts.createTypeLiteralNode(typeElements) : undefined;
                        if (typeLiteral) {
                            ts.setEmitFlags(typeLiteral, 1 /* SingleLine */);
                        }
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createObjectBindingPattern(bindingElements), 
                            /*type*/ typeLiteral, 
                            /*initializer*/ call)], commonNodeFlags)));
                    }
                }
                else if (exposedVariableDeclarations.length || writes) {
                    if (exposedVariableDeclarations.length) {
                        // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping.
                        for (var _c = 0, exposedVariableDeclarations_2 = exposedVariableDeclarations; _c < exposedVariableDeclarations_2.length; _c++) {
                            var variableDeclaration = exposedVariableDeclarations_2[_c];
                            var flags = variableDeclaration.parent.flags;
                            if (flags & 2 /* Const */) {
                                flags = (flags & ~2 /* Const */) | 1 /* Let */;
                            }
                            newNodes.push(ts.createVariableStatement(
                            /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags)));
                        }
                    }
                    if (returnValueProperty) {
                        // has both writes and return, need to create variable declaration to hold return value;
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], 1 /* Let */)));
                    }
                    var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                    if (returnValueProperty) {
                        assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty));
                    }
                    // propagate writes back
                    if (assignments.length === 1) {
                        // We would only have introduced a return value property if there had been
                        // other assignments to make.
                        ts.Debug.assert(!returnValueProperty);
                        newNodes.push(ts.createStatement(ts.createAssignment(assignments[0].name, call)));
                        if (range.facts & RangeFacts.HasReturn) {
                            newNodes.push(ts.createReturn());
                        }
                    }
                    else {
                        // emit e.g.
                        //   { a, b, __return } = newFunction(a, b);
                        //   return __return;
                        newNodes.push(ts.createStatement(ts.createAssignment(ts.createObjectLiteral(assignments), call)));
                        if (returnValueProperty) {
                            newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty)));
                        }
                    }
                }
                else {
                    if (range.facts & RangeFacts.HasReturn) {
                        newNodes.push(ts.createReturn(call));
                    }
                    else if (isReadonlyArray(range.range)) {
                        newNodes.push(ts.createStatement(call));
                    }
                    else {
                        newNodes.push(call);
                    }
                }
                var replacementRange = isReadonlyArray(range.range)
                    ? { pos: ts.first(range.range).getStart(), end: ts.last(range.range).end }
                    : { pos: range.range.getStart(), end: range.range.end };
                changeTracker.replaceRangeWithNodes(context.file, replacementRange, newNodes, { nodeSeparator: context.newLineCharacter });
                var edits = changeTracker.getChanges();
                var renameRange = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
                var renameFilename = renameRange.getSourceFile().fileName;
                var renameLocation = getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false);
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
                function getTypeDeepCloneUnionUndefined(typeNode) {
                    if (typeNode === undefined) {
                        return undefined;
                    }
                    var clone = ts.getSynthesizedDeepClone(typeNode);
                    var withoutParens = clone;
                    while (ts.isParenthesizedTypeNode(withoutParens)) {
                        withoutParens = withoutParens.type;
                    }
                    return ts.isUnionTypeNode(withoutParens) && ts.find(withoutParens.types, function (t) { return t.kind === 139 /* UndefinedKeyword */; })
                        ? clone
                        : ts.createUnionTypeNode([clone, ts.createKeywordTypeNode(139 /* UndefinedKeyword */)]);
                }
            }
            /**
             * Result of 'extractRange' operation for a specific scope.
             * Stores either a list of changes that should be applied to extract a range or a list of errors
             */
            function extractConstantInScope(node, scope, _a, rangeFacts, context) {
                var substitutions = _a.substitutions;
                var checker = context.program.getTypeChecker();
                // Make a unique name for the extracted variable
                var file = scope.getSourceFile();
                var localNameText = getUniqueName(ts.isClassLike(scope) ? "newProperty" : "newLocal", file.text);
                var isJS = ts.isInJavaScriptFile(scope);
                var variableType = isJS
                    ? undefined
                    : checker.typeToTypeNode(checker.getContextualType(node), scope, ts.NodeBuilderFlags.NoTruncation);
                var initializer = transformConstantInitializer(node, substitutions);
                ts.suppressLeadingAndTrailingTrivia(initializer);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                if (ts.isClassLike(scope)) {
                    ts.Debug.assert(!isJS); // See CannotExtractToJSClass
                    var modifiers = [];
                    modifiers.push(ts.createToken(112 /* PrivateKeyword */));
                    if (rangeFacts & RangeFacts.InStaticRegion) {
                        modifiers.push(ts.createToken(115 /* StaticKeyword */));
                    }
                    modifiers.push(ts.createToken(131 /* ReadonlyKeyword */));
                    var newVariable = ts.createProperty(
                    /*decorators*/ undefined, modifiers, localNameText, 
                    /*questionToken*/ undefined, variableType, initializer);
                    var localReference = ts.createPropertyAccess(rangeFacts & RangeFacts.InStaticRegion
                        ? ts.createIdentifier(scope.name.getText())
                        : ts.createThis(), ts.createIdentifier(localNameText));
                    // Declare
                    var maxInsertionPos = node.pos;
                    var nodeToInsertBefore = getNodeToInsertPropertyBefore(maxInsertionPos, scope);
                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter });
                    // Consume
                    changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
                }
                else {
                    var newVariableDeclaration = ts.createVariableDeclaration(localNameText, variableType, initializer);
                    // If the node is part of an initializer in a list of variable declarations, insert a new
                    // variable declaration into the list (in case it depends on earlier ones).
                    // CONSIDER: If the declaration list isn't const, we might want to split it into multiple
                    // lists so that the newly extracted one can be const.
                    var oldVariableDeclaration = getContainingVariableDeclarationIfInList(node, scope);
                    if (oldVariableDeclaration) {
                        // Declare
                        // CONSIDER: could detect that each is on a separate line
                        changeTracker.insertNodeAt(context.file, oldVariableDeclaration.getStart(), newVariableDeclaration, { suffix: ", " });
                        // Consume
                        var localReference = ts.createIdentifier(localNameText);
                        changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
                    }
                    else if (node.parent.kind === 210 /* ExpressionStatement */ && scope === ts.findAncestor(node, isScope)) {
                        // If the parent is an expression statement and the target scope is the immediately enclosing one,
                        // replace the statement with the declaration.
                        var newVariableStatement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
                        changeTracker.replaceRange(context.file, { pos: node.parent.getStart(), end: node.parent.end }, newVariableStatement);
                    }
                    else {
                        var newVariableStatement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
                        // Declare
                        var nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope);
                        if (nodeToInsertBefore.pos === 0) {
                            // If we're at the beginning of the file, we need to take care not to insert before header comments
                            // (e.g. copyright, triple-slash references).  Fortunately, this problem has already been solved
                            // for imports.
                            var insertionPos = ts.getSourceFileImportLocation(file);
                            changeTracker.insertNodeAt(context.file, insertionPos, newVariableStatement, {
                                prefix: insertionPos === 0 ? undefined : context.newLineCharacter,
                                suffix: ts.isLineBreak(file.text.charCodeAt(insertionPos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter
                            });
                        }
                        else {
                            changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariableStatement, { suffix: context.newLineCharacter + context.newLineCharacter });
                        }
                        // Consume
                        if (node.parent.kind === 210 /* ExpressionStatement */) {
                            // If the parent is an expression statement, delete it.
                            changeTracker.deleteRange(context.file, { pos: node.parent.getStart(), end: node.parent.end });
                        }
                        else {
                            var localReference = ts.createIdentifier(localNameText);
                            changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
                        }
                    }
                }
                var edits = changeTracker.getChanges();
                var renameFilename = node.getSourceFile().fileName;
                var renameLocation = getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true);
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
            }
            function getContainingVariableDeclarationIfInList(node, scope) {
                var prevNode = undefined;
                while (node !== undefined && node !== scope) {
                    if (ts.isVariableDeclaration(node) &&
                        node.initializer === prevNode &&
                        ts.isVariableDeclarationList(node.parent) &&
                        node.parent.declarations.length > 1) {
                        return node;
                    }
                    prevNode = node;
                    node = node.parent;
                }
            }
            /**
             * @return The index of the (only) reference to the extracted symbol.  We want the cursor
             * to be on the reference, rather than the declaration, because it's closer to where the
             * user was before extracting it.
             */
            function getRenameLocation(edits, renameFilename, functionNameText, isDeclaredBeforeUse) {
                var delta = 0;
                var lastPos = -1;
                for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) {
                    var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges;
                    ts.Debug.assert(fileName === renameFilename);
                    for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) {
                        var change = textChanges_2[_b];
                        var span_17 = change.span, newText = change.newText;
                        var index = newText.indexOf(functionNameText);
                        if (index !== -1) {
                            lastPos = span_17.start + delta + index;
                            // If the reference comes first, return immediately.
                            if (!isDeclaredBeforeUse) {
                                return lastPos;
                            }
                        }
                        delta += newText.length - span_17.length;
                    }
                }
                // If the declaration comes first, return the position of the last occurrence.
                ts.Debug.assert(isDeclaredBeforeUse);
                ts.Debug.assert(lastPos >= 0);
                return lastPos;
            }
            function getFirstDeclaration(type) {
                var firstDeclaration = undefined;
                var symbol = type.symbol;
                if (symbol && symbol.declarations) {
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) {
                            firstDeclaration = declaration;
                        }
                    }
                }
                return firstDeclaration;
            }
            function compareTypesByDeclarationOrder(_a, _b) {
                var type1 = _a.type, declaration1 = _a.declaration;
                var type2 = _b.type, declaration2 = _b.declaration;
                if (declaration1) {
                    if (declaration2) {
                        var positionDiff = declaration1.pos - declaration2.pos;
                        if (positionDiff !== 0) {
                            return positionDiff;
                        }
                    }
                    else {
                        return 1; // Sort undeclared type parameters to the front.
                    }
                }
                else if (declaration2) {
                    return -1; // Sort undeclared type parameters to the front.
                }
                var name1 = type1.symbol ? type1.symbol.getName() : "";
                var name2 = type2.symbol ? type2.symbol.getName() : "";
                var nameDiff = ts.compareStrings(name1, name2);
                if (nameDiff !== 0) {
                    return nameDiff;
                }
                // IDs are guaranteed to be unique, so this ensures a total ordering.
                return type1.id - type2.id;
            }
            function getCalledExpression(scope, range, functionNameText) {
                var functionReference = ts.createIdentifier(functionNameText);
                if (ts.isClassLike(scope)) {
                    var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis();
                    return ts.createPropertyAccess(lhs, functionReference);
                }
                else {
                    return functionReference;
                }
            }
            function transformFunctionBody(body, exposedVariableDeclarations, writes, substitutions, hasReturn) {
                var hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0;
                if (ts.isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) {
                    // already block, no declarations or writes to propagate back, no substitutions - can use node as is
                    return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
                }
                var returnValueProperty;
                var ignoreReturns = false;
                var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]);
                // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
                if (hasWritesOrVariableDeclarations || substitutions.size) {
                    var rewrittenStatements = ts.visitNodes(statements, visitor).slice();
                    if (hasWritesOrVariableDeclarations && !hasReturn && ts.isStatement(body)) {
                        // add return at the end to propagate writes back in case if control flow falls out of the function body
                        // it is ok to know that range has at least one return since it we only allow unconditional returns
                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                        if (assignments.length === 1) {
                            rewrittenStatements.push(ts.createReturn(assignments[0].name));
                        }
                        else {
                            rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments)));
                        }
                    }
                    return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty };
                }
                else {
                    return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined };
                }
                function visitor(node) {
                    if (!ignoreReturns && node.kind === 219 /* ReturnStatement */ && hasWritesOrVariableDeclarations) {
                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                        if (node.expression) {
                            if (!returnValueProperty) {
                                returnValueProperty = "__return";
                            }
                            assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor)));
                        }
                        if (assignments.length === 1) {
                            return ts.createReturn(assignments[0].name);
                        }
                        else {
                            return ts.createReturn(ts.createObjectLiteral(assignments));
                        }
                    }
                    else {
                        var oldIgnoreReturns = ignoreReturns;
                        ignoreReturns = ignoreReturns || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node);
                        var substitution = substitutions.get(ts.getNodeId(node).toString());
                        var result = substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
                        ignoreReturns = oldIgnoreReturns;
                        return result;
                    }
                }
            }
            function transformConstantInitializer(initializer, substitutions) {
                return substitutions.size
                    ? visitor(initializer)
                    : initializer;
                function visitor(node) {
                    var substitution = substitutions.get(ts.getNodeId(node).toString());
                    return substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
                }
            }
            function getStatementsOrClassElements(scope) {
                if (ts.isFunctionLikeDeclaration(scope)) {
                    var body = scope.body;
                    if (ts.isBlock(body)) {
                        return body.statements;
                    }
                }
                else if (ts.isModuleBlock(scope) || ts.isSourceFile(scope)) {
                    return scope.statements;
                }
                else if (ts.isClassLike(scope)) {
                    return scope.members;
                }
                else {
                    ts.assertTypeIsNever(scope);
                }
                return ts.emptyArray;
            }
            /**
             * If `scope` contains a function after `minPos`, then return the first such function.
             * Otherwise, return `undefined`.
             */
            function getNodeToInsertFunctionBefore(minPos, scope) {
                return ts.find(getStatementsOrClassElements(scope), function (child) {
                    return child.pos >= minPos && ts.isFunctionLikeDeclaration(child) && !ts.isConstructorDeclaration(child);
                });
            }
            function getNodeToInsertPropertyBefore(maxPos, scope) {
                var members = scope.members;
                ts.Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one.
                var prevMember = undefined;
                var allProperties = true;
                for (var _i = 0, members_5 = members; _i < members_5.length; _i++) {
                    var member = members_5[_i];
                    if (member.pos > maxPos) {
                        return prevMember || members[0];
                    }
                    if (allProperties && !ts.isPropertyDeclaration(member)) {
                        // If it is non-vacuously true that all preceding members are properties,
                        // insert before the current member (i.e. at the end of the list of properties).
                        if (prevMember !== undefined) {
                            return member;
                        }
                        allProperties = false;
                    }
                    prevMember = member;
                }
                ts.Debug.assert(prevMember !== undefined); // If the loop didn't return, then it did set prevMember.
                return prevMember;
            }
            function getNodeToInsertConstantBefore(node, scope) {
                ts.Debug.assert(!ts.isClassLike(scope));
                var prevScope = undefined;
                for (var curr = node; curr !== scope; curr = curr.parent) {
                    if (isScope(curr)) {
                        prevScope = curr;
                    }
                }
                for (var curr = (prevScope || node).parent;; curr = curr.parent) {
                    if (isBlockLike(curr)) {
                        var prevStatement = undefined;
                        for (var _i = 0, _a = curr.statements; _i < _a.length; _i++) {
                            var statement = _a[_i];
                            if (statement.pos > node.pos) {
                                break;
                            }
                            prevStatement = statement;
                        }
                        // There must be at least one statement since we started in one.
                        ts.Debug.assert(prevStatement !== undefined);
                        return prevStatement;
                    }
                    if (curr === scope) {
                        ts.Debug.fail("Didn't encounter a block-like before encountering scope");
                        break;
                    }
                }
            }
            function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes) {
                var variableAssignments = ts.map(exposedVariableDeclarations, function (v) { return ts.createShorthandPropertyAssignment(v.symbol.name); });
                var writeAssignments = ts.map(writes, function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); });
                return variableAssignments === undefined
                    ? writeAssignments
                    : writeAssignments === undefined
                        ? variableAssignments
                        : variableAssignments.concat(writeAssignments);
            }
            function isReadonlyArray(v) {
                return ts.isArray(v);
            }
            /**
             * Produces a range that spans the entirety of nodes, given a selection
             * that might start/end in the middle of nodes.
             *
             * For example, when the user makes a selection like this
             *                     v---v
             *   var someThing = foo + bar;
             *  this returns     ^-------^
             */
            function getEnclosingTextRange(targetRange, sourceFile) {
                return isReadonlyArray(targetRange.range)
                    ? { pos: ts.first(targetRange.range).getStart(sourceFile), end: ts.last(targetRange.range).getEnd() }
                    : targetRange.range;
            }
            var Usage;
            (function (Usage) {
                // value should be passed to extracted method
                Usage[Usage["Read"] = 1] = "Read";
                // value should be passed to extracted method and propagated back
                Usage[Usage["Write"] = 2] = "Write";
            })(Usage || (Usage = {}));
            function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker, cancellationToken) {
                var allTypeParameterUsages = ts.createMap(); // Key is type ID
                var usagesPerScope = [];
                var substitutionsPerScope = [];
                var functionErrorsPerScope = [];
                var constantErrorsPerScope = [];
                var visibleDeclarationsInExtractedRange = [];
                var exposedVariableSymbolSet = ts.createMap(); // Key is symbol ID
                var exposedVariableDeclarations = [];
                var firstExposedNonVariableDeclaration = undefined;
                var expression = !isReadonlyArray(targetRange.range)
                    ? targetRange.range
                    : targetRange.range.length === 1 && ts.isExpressionStatement(targetRange.range[0])
                        ? targetRange.range[0].expression
                        : undefined;
                var expressionDiagnostic = undefined;
                if (expression === undefined) {
                    var statements = targetRange.range;
                    var start = ts.first(statements).getStart();
                    var end = ts.last(statements).end;
                    expressionDiagnostic = ts.createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected);
                }
                else if (checker.getTypeAtLocation(expression).flags & (1024 /* Void */ | 8192 /* Never */)) {
                    expressionDiagnostic = ts.createDiagnosticForNode(expression, Messages.UselessConstantType);
                }
                // initialize results
                for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) {
                    var scope = scopes_1[_i];
                    usagesPerScope.push({ usages: ts.createMap(), typeParameterUsages: ts.createMap(), substitutions: ts.createMap() });
                    substitutionsPerScope.push(ts.createMap());
                    functionErrorsPerScope.push(ts.isFunctionLikeDeclaration(scope) && scope.kind !== 228 /* FunctionDeclaration */
                        ? [ts.createDiagnosticForNode(scope, Messages.CannotExtractToOtherFunctionLike)]
                        : []);
                    var constantErrors = [];
                    if (expressionDiagnostic) {
                        constantErrors.push(expressionDiagnostic);
                    }
                    if (ts.isClassLike(scope) && ts.isInJavaScriptFile(scope)) {
                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.CannotExtractToJSClass));
                    }
                    if (ts.isArrowFunction(scope) && !ts.isBlock(scope.body)) {
                        // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this
                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.CannotExtractToExpressionArrowFunction));
                    }
                    constantErrorsPerScope.push(constantErrors);
                }
                var seenUsages = ts.createMap();
                var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range;
                var unmodifiedNode = isReadonlyArray(targetRange.range) ? ts.first(targetRange.range) : targetRange.range;
                var inGenericContext = isInGenericContext(unmodifiedNode);
                collectUsages(target);
                // Unfortunately, this code takes advantage of the knowledge that the generated method
                // will use the contextual type of an expression as the return type of the extracted
                // method (and will therefore "use" all the types involved).
                if (inGenericContext && !isReadonlyArray(targetRange.range)) {
                    var contextualType = checker.getContextualType(targetRange.range);
                    recordTypeParameterUsages(contextualType);
                }
                if (allTypeParameterUsages.size > 0) {
                    var seenTypeParameterUsages = ts.createMap(); // Key is type ID
                    var i_1 = 0;
                    for (var curr = unmodifiedNode; curr !== undefined && i_1 < scopes.length; curr = curr.parent) {
                        if (curr === scopes[i_1]) {
                            // Copy current contents of seenTypeParameterUsages into scope.
                            seenTypeParameterUsages.forEach(function (typeParameter, id) {
                                usagesPerScope[i_1].typeParameterUsages.set(id, typeParameter);
                            });
                            i_1++;
                        }
                        // Note that we add the current node's type parameters *after* updating the corresponding scope.
                        if (ts.isDeclarationWithTypeParameters(curr) && curr.typeParameters) {
                            for (var _a = 0, _b = curr.typeParameters; _a < _b.length; _a++) {
                                var typeParameterDecl = _b[_a];
                                var typeParameter = checker.getTypeAtLocation(typeParameterDecl);
                                if (allTypeParameterUsages.has(typeParameter.id.toString())) {
                                    seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter);
                                }
                            }
                        }
                    }
                    // If we didn't get through all the scopes, then there were some that weren't in our
                    // parent chain (impossible at time of writing).  A conservative solution would be to
                    // copy allTypeParameterUsages into all remaining scopes.
                    ts.Debug.assert(i_1 === scopes.length);
                }
                // If there are any declarations in the extracted block that are used in the same enclosing
                // lexical scope, we can't move the extraction "up" as those declarations will become unreachable
                if (visibleDeclarationsInExtractedRange.length) {
                    var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent)
                        ? scopes[0]
                        : ts.getEnclosingBlockScopeContainer(scopes[0]);
                    ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations);
                }
                var _loop_8 = function (i) {
                    var scopeUsages = usagesPerScope[i];
                    // Special case: in the innermost scope, all usages are available.
                    // (The computed value reflects the value at the top-level of the scope, but the
                    // local will actually be declared at the same level as the extracted expression).
                    if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) {
                        var errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range;
                        constantErrorsPerScope[i].push(ts.createDiagnosticForNode(errorNode, Messages.CannotAccessVariablesFromNestedScopes));
                    }
                    var hasWrite = false;
                    var readonlyClassPropertyWrite = undefined;
                    usagesPerScope[i].usages.forEach(function (value) {
                        if (value.usage === 2 /* Write */) {
                            hasWrite = true;
                            if (value.symbol.flags & 106500 /* ClassMember */ &&
                                value.symbol.valueDeclaration &&
                                ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) {
                                readonlyClassPropertyWrite = value.symbol.valueDeclaration;
                            }
                        }
                    });
                    // If an expression was extracted, then there shouldn't have been any variable declarations.
                    ts.Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0);
                    if (hasWrite && !isReadonlyArray(targetRange.range)) {
                        var diag = ts.createDiagnosticForNode(targetRange.range, Messages.CannotWriteInExpression);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                    else if (readonlyClassPropertyWrite && i > 0) {
                        var diag = ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                    else if (firstExposedNonVariableDeclaration) {
                        var diag = ts.createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.CannotExtractExportedEntity);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                };
                for (var i = 0; i < scopes.length; i++) {
                    _loop_8(i);
                }
                return { target: target, usagesPerScope: usagesPerScope, functionErrorsPerScope: functionErrorsPerScope, constantErrorsPerScope: constantErrorsPerScope, exposedVariableDeclarations: exposedVariableDeclarations };
                function hasTypeParameters(node) {
                    return ts.isDeclarationWithTypeParameters(node) &&
                        node.typeParameters !== undefined &&
                        node.typeParameters.length > 0;
                }
                function isInGenericContext(node) {
                    for (; node; node = node.parent) {
                        if (hasTypeParameters(node)) {
                            return true;
                        }
                    }
                    return false;
                }
                function recordTypeParameterUsages(type) {
                    // PERF: This is potentially very expensive.  `type` could be a library type with
                    // a lot of properties, each of which the walker will visit.  Unfortunately, the
                    // solution isn't as trivial as filtering to user types because of (e.g.) Array.
                    var symbolWalker = checker.getSymbolWalker(function () { return (cancellationToken.throwIfCancellationRequested(), true); });
                    var visitedTypes = symbolWalker.walkType(type).visitedTypes;
                    for (var _i = 0, visitedTypes_1 = visitedTypes; _i < visitedTypes_1.length; _i++) {
                        var visitedType = visitedTypes_1[_i];
                        if (visitedType.flags & 16384 /* TypeParameter */) {
                            allTypeParameterUsages.set(visitedType.id.toString(), visitedType);
                        }
                    }
                }
                function collectUsages(node, valueUsage) {
                    if (valueUsage === void 0) { valueUsage = 1 /* Read */; }
                    if (inGenericContext) {
                        var type = checker.getTypeAtLocation(node);
                        recordTypeParameterUsages(type);
                    }
                    if (ts.isDeclaration(node) && node.symbol) {
                        visibleDeclarationsInExtractedRange.push(node);
                    }
                    if (ts.isAssignmentExpression(node)) {
                        // use 'write' as default usage for values
                        collectUsages(node.left, 2 /* Write */);
                        collectUsages(node.right);
                    }
                    else if (ts.isUnaryExpressionWithWrite(node)) {
                        collectUsages(node.operand, 2 /* Write */);
                    }
                    else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
                        // use 'write' as default usage for values
                        ts.forEachChild(node, collectUsages);
                    }
                    else if (ts.isIdentifier(node)) {
                        if (!node.parent) {
                            return;
                        }
                        if (ts.isQualifiedName(node.parent) && node !== node.parent.left) {
                            return;
                        }
                        if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) {
                            return;
                        }
                        recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node));
                    }
                    else {
                        ts.forEachChild(node, collectUsages);
                    }
                }
                function recordUsage(n, usage, isTypeNode) {
                    var symbolId = recordUsagebySymbol(n, usage, isTypeNode);
                    if (symbolId) {
                        for (var i = 0; i < scopes.length; i++) {
                            // push substitution from map<symbolId, subst> to map<nodeId, subst> to simplify rewriting
                            var substitution = substitutionsPerScope[i].get(symbolId);
                            if (substitution) {
                                usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitution);
                            }
                        }
                    }
                }
                function recordUsagebySymbol(identifier, usage, isTypeName) {
                    var symbol = getSymbolReferencedByIdentifier(identifier);
                    if (!symbol) {
                        // cannot find symbol - do nothing
                        return undefined;
                    }
                    var symbolId = ts.getSymbolId(symbol).toString();
                    var lastUsage = seenUsages.get(symbolId);
                    // there are two kinds of value usages
                    // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter
                    // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and
                    //   returned as a return value
                    // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read'
                    // since all information is already recorded
                    if (lastUsage && lastUsage >= usage) {
                        return symbolId;
                    }
                    seenUsages.set(symbolId, usage);
                    if (lastUsage) {
                        // if we get here this means that we are trying to handle 'write' and 'read' was already processed
                        // walk scopes and update existing records.
                        for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) {
                            var perScope = usagesPerScope_1[_i];
                            var prevEntry = perScope.usages.get(identifier.text);
                            if (prevEntry) {
                                perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
                            }
                        }
                        return symbolId;
                    }
                    // find first declaration in this file
                    var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; });
                    if (!declInFile) {
                        return undefined;
                    }
                    if (ts.rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) {
                        // declaration is located in range to be extracted - do nothing
                        return undefined;
                    }
                    if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) {
                        // this is write to a reference located outside of the target scope and range is extracted into generator
                        // currently this is unsupported scenario
                        var diag = ts.createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators);
                        for (var _a = 0, functionErrorsPerScope_1 = functionErrorsPerScope; _a < functionErrorsPerScope_1.length; _a++) {
                            var errors = functionErrorsPerScope_1[_a];
                            errors.push(diag);
                        }
                        for (var _b = 0, constantErrorsPerScope_1 = constantErrorsPerScope; _b < constantErrorsPerScope_1.length; _b++) {
                            var errors = constantErrorsPerScope_1[_b];
                            errors.push(diag);
                        }
                    }
                    for (var i = 0; i < scopes.length; i++) {
                        var scope = scopes[i];
                        var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags);
                        if (resolvedSymbol === symbol) {
                            continue;
                        }
                        if (!substitutionsPerScope[i].has(symbolId)) {
                            var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName);
                            if (substitution) {
                                substitutionsPerScope[i].set(symbolId, substitution);
                            }
                            else if (isTypeName) {
                                // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument
                                // so there's no problem.
                                if (!(symbol.flags & 262144 /* TypeParameter */)) {
                                    var diag = ts.createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope);
                                    functionErrorsPerScope[i].push(diag);
                                    constantErrorsPerScope[i].push(diag);
                                }
                            }
                            else {
                                usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
                            }
                        }
                    }
                    return symbolId;
                }
                function checkForUsedDeclarations(node) {
                    // If this node is entirely within the original extraction range, we don't need to do anything.
                    if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) {
                        return;
                    }
                    // Otherwise check and recurse.
                    var sym = ts.isIdentifier(node)
                        ? getSymbolReferencedByIdentifier(node)
                        : checker.getSymbolAtLocation(node);
                    if (sym) {
                        var decl = ts.find(visibleDeclarationsInExtractedRange, function (d) { return d.symbol === sym; });
                        if (decl) {
                            if (ts.isVariableDeclaration(decl)) {
                                var idString = decl.symbol.id.toString();
                                if (!exposedVariableSymbolSet.has(idString)) {
                                    exposedVariableDeclarations.push(decl);
                                    exposedVariableSymbolSet.set(idString, true);
                                }
                            }
                            else {
                                // CONSIDER: this includes binding elements, which we could
                                // expose in the same way as variables.
                                firstExposedNonVariableDeclaration = firstExposedNonVariableDeclaration || decl;
                            }
                        }
                    }
                    ts.forEachChild(node, checkForUsedDeclarations);
                }
                /**
                 * Return the symbol referenced by an identifier (even if it declares a different symbol).
                 */
                function getSymbolReferencedByIdentifier(identifier) {
                    // If the identifier is both a property name and its value, we're only interested in its value
                    // (since the name is a declaration and will be included in the extracted range).
                    return identifier.parent && ts.isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier
                        ? checker.getShorthandAssignmentValueSymbol(identifier.parent)
                        : checker.getSymbolAtLocation(identifier);
                }
                function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) {
                    if (!symbol) {
                        return undefined;
                    }
                    if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) {
                        return ts.createIdentifier(symbol.name);
                    }
                    var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode);
                    if (prefix === undefined) {
                        return undefined;
                    }
                    return isTypeNode
                        ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name))
                        : ts.createPropertyAccess(prefix, symbol.name);
                }
            }
            function getParentNodeInSpan(node, file, span) {
                if (!node)
                    return undefined;
                while (node.parent) {
                    if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) {
                        return node;
                    }
                    node = node.parent;
                }
            }
            function spanContainsNode(span, node, file) {
                return ts.textSpanContainsPosition(span, node.getStart(file)) &&
                    node.getEnd() <= ts.textSpanEnd(span);
            }
            /**
             * Computes whether or not a node represents an expression in a position where it could
             * be extracted.
             * The isExpression() in utilities.ts returns some false positives we need to handle,
             * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression
             * in the sense of something that you could extract on
             */
            function isExtractableExpression(node) {
                switch (node.parent.kind) {
                    case 264 /* EnumMember */:
                        return false;
                }
                switch (node.kind) {
                    case 9 /* StringLiteral */:
                        return node.parent.kind !== 238 /* ImportDeclaration */ &&
                            node.parent.kind !== 242 /* ImportSpecifier */;
                    case 198 /* SpreadElement */:
                    case 174 /* ObjectBindingPattern */:
                    case 176 /* BindingElement */:
                        return false;
                    case 71 /* Identifier */:
                        return node.parent.kind !== 176 /* BindingElement */ &&
                            node.parent.kind !== 242 /* ImportSpecifier */ &&
                            node.parent.kind !== 246 /* ExportSpecifier */;
                }
                return true;
            }
            function isBlockLike(node) {
                switch (node.kind) {
                    case 207 /* Block */:
                    case 265 /* SourceFile */:
                    case 234 /* ModuleBlock */:
                    case 257 /* CaseClause */:
                        return true;
                    default:
                        return false;
                }
            }
        })(extractSymbol = refactor.extractSymbol || (refactor.extractSymbol = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var installTypesForPackage;
        (function (installTypesForPackage_1) {
            var actionName = "install";
            var installTypesForPackage = {
                name: "Install missing types package",
                description: "Install missing types package",
                getEditsForAction: getEditsForAction,
                getAvailableActions: getAvailableActions,
            };
            refactor.registerRefactor(installTypesForPackage);
            function getAvailableActions(context) {
                var options = context.program.getCompilerOptions();
                var noImplicitAny = options.noImplicitAny === undefined ? options.strict : options.noImplicitAny;
                if (noImplicitAny) {
                    // Then it will be available via `fixCannotFindModule`.
                    return undefined;
                }
                var action = getAction(context);
                return action && [
                    {
                        name: installTypesForPackage.name,
                        description: installTypesForPackage.description,
                        actions: [
                            {
                                description: action.description,
                                name: actionName,
                            },
                        ],
                    },
                ];
            }
            function getEditsForAction(context, _actionName) {
                ts.Debug.assertEqual(actionName, _actionName);
                var action = getAction(context); // Should be defined if we said there was an action available.
                return {
                    edits: [],
                    renameFilename: undefined,
                    renameLocation: undefined,
                    commands: action.commands,
                };
            }
            function getAction(context) {
                var file = context.file, startPosition = context.startPosition;
                var node = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
                if (ts.isStringLiteral(node) && isModuleIdentifier(node) && ts.getResolvedModule(file, node.text) === undefined) {
                    return ts.codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
                }
            }
            function isModuleIdentifier(node) {
                switch (node.parent.kind) {
                    case 238 /* ImportDeclaration */:
                    case 248 /* ExternalModuleReference */:
                        return true;
                    default:
                        return false;
                }
            }
        })(installTypesForPackage = refactor.installTypesForPackage || (refactor.installTypesForPackage = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/// <reference path="annotateWithTypeFromJSDoc.ts" />
/// <reference path="convertFunctionToEs6Class.ts" />
/// <reference path="extractSymbol.ts" />
/// <reference path="installTypesForPackage.ts" />
/// <reference path="..\compiler\program.ts"/>
/// <reference path="..\compiler\commandLineParser.ts"/>
/// <reference path='types.ts' />
/// <reference path='utilities.ts' />
/// <reference path='breakpoints.ts' />
/// <reference path='classifier.ts' />
/// <reference path='completions.ts' />
/// <reference path='documentHighlights.ts' />
/// <reference path='documentRegistry.ts' />
/// <reference path='findAllReferences.ts' />
/// <reference path='goToDefinition.ts' />
/// <reference path='jsDoc.ts' />
/// <reference path='jsTyping.ts' />
/// <reference path='navigateTo.ts' />
/// <reference path='navigationBar.ts' />
/// <reference path='outliningElementsCollector.ts' />
/// <reference path='patternMatcher.ts' />
/// <reference path='preProcess.ts' />
/// <reference path='rename.ts' />
/// <reference path='signatureHelp.ts' />
/// <reference path='symbolDisplay.ts' />
/// <reference path='transpile.ts' />
/// <reference path='formatting\formatting.ts' />
/// <reference path='formatting\smartIndenter.ts' />
/// <reference path='textChanges.ts' />
/// <reference path='codeFixProvider.ts' />
/// <reference path='refactorProvider.ts' />
/// <reference path='codefixes\fixes.ts' />
/// <reference path='refactors\refactors.ts' />
var ts;
(function (ts) {
    /** The version of the language service API */
    ts.servicesVersion = "0.6";
    /* @internal */
    var ruleProvider;
    function createNode(kind, pos, end, parent) {
        var node = ts.isNodeKind(kind) ? new NodeObject(kind, pos, end) :
            kind === 71 /* Identifier */ ? new IdentifierObject(71 /* Identifier */, pos, end) :
                new TokenObject(kind, pos, end);
        node.parent = parent;
        return node;
    }
    var NodeObject = /** @class */ (function () {
        function NodeObject(kind, pos, end) {
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.transformFlags = undefined;
            this.parent = undefined;
            this.kind = kind;
        }
        NodeObject.prototype.getSourceFile = function () {
            return ts.getSourceFileOfNode(this);
        };
        NodeObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
        };
        NodeObject.prototype.getFullStart = function () {
            return this.pos;
        };
        NodeObject.prototype.getEnd = function () {
            return this.end;
        };
        NodeObject.prototype.getWidth = function (sourceFile) {
            return this.getEnd() - this.getStart(sourceFile);
        };
        NodeObject.prototype.getFullWidth = function () {
            return this.end - this.pos;
        };
        NodeObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
            return this.getStart(sourceFile) - this.pos;
        };
        NodeObject.prototype.getFullText = function (sourceFile) {
            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
        };
        NodeObject.prototype.getText = function (sourceFile) {
            if (!sourceFile) {
                sourceFile = this.getSourceFile();
            }
            return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
        };
        NodeObject.prototype.addSyntheticNodes = function (nodes, pos, end) {
            ts.scanner.setTextPos(pos);
            while (pos < end) {
                var token = ts.scanner.scan();
                var textPos = ts.scanner.getTextPos();
                if (textPos <= end) {
                    nodes.push(createNode(token, pos, textPos, this));
                }
                pos = textPos;
                if (token === 1 /* EndOfFileToken */) {
                    break;
                }
            }
            return pos;
        };
        NodeObject.prototype.createSyntaxList = function (nodes) {
            var list = createNode(286 /* SyntaxList */, nodes.pos, nodes.end, this);
            list._children = [];
            var pos = nodes.pos;
            for (var _i = 0, nodes_9 = nodes; _i < nodes_9.length; _i++) {
                var node = nodes_9[_i];
                if (pos < node.pos) {
                    pos = this.addSyntheticNodes(list._children, pos, node.pos);
                }
                list._children.push(node);
                pos = node.end;
            }
            if (pos < nodes.end) {
                this.addSyntheticNodes(list._children, pos, nodes.end);
            }
            return list;
        };
        NodeObject.prototype.createChildren = function (sourceFile) {
            var _this = this;
            if (!ts.isNodeKind(this.kind)) {
                this._children = ts.emptyArray;
                return;
            }
            if (ts.isJSDocCommentContainingNode(this)) {
                /** Don't add trivia for "tokens" since this is in a comment. */
                var children_3 = [];
                this.forEachChild(function (child) { children_3.push(child); });
                this._children = children_3;
                return;
            }
            var children = [];
            ts.scanner.setText((sourceFile || this.getSourceFile()).text);
            var pos = this.pos;
            var processNode = function (node) {
                pos = _this.addSyntheticNodes(children, pos, node.pos);
                children.push(node);
                pos = node.end;
            };
            var processNodes = function (nodes) {
                if (pos < nodes.pos) {
                    pos = _this.addSyntheticNodes(children, pos, nodes.pos);
                }
                children.push(_this.createSyntaxList(nodes));
                pos = nodes.end;
            };
            // jsDocComments need to be the first children
            if (this.jsDoc) {
                for (var _i = 0, _a = this.jsDoc; _i < _a.length; _i++) {
                    var jsDocComment = _a[_i];
                    processNode(jsDocComment);
                }
            }
            // For syntactic classifications, all trivia are classcified together, including jsdoc comments.
            // For that to work, the jsdoc comments should still be the leading trivia of the first child.
            // Restoring the scanner position ensures that.
            pos = this.pos;
            ts.forEachChild(this, processNode, processNodes);
            if (pos < this.end) {
                this.addSyntheticNodes(children, pos, this.end);
            }
            ts.scanner.setText(undefined);
            this._children = children;
        };
        NodeObject.prototype.getChildCount = function (sourceFile) {
            if (!this._children)
                this.createChildren(sourceFile);
            return this._children.length;
        };
        NodeObject.prototype.getChildAt = function (index, sourceFile) {
            if (!this._children)
                this.createChildren(sourceFile);
            return this._children[index];
        };
        NodeObject.prototype.getChildren = function (sourceFile) {
            if (!this._children)
                this.createChildren(sourceFile);
            return this._children;
        };
        NodeObject.prototype.getFirstToken = function (sourceFile) {
            var children = this.getChildren(sourceFile);
            if (!children.length) {
                return undefined;
            }
            var child = ts.find(children, function (kid) { return kid.kind < 267 /* FirstJSDocNode */ || kid.kind > 285 /* LastJSDocNode */; });
            return child.kind < 143 /* FirstNode */ ?
                child :
                child.getFirstToken(sourceFile);
        };
        NodeObject.prototype.getLastToken = function (sourceFile) {
            var children = this.getChildren(sourceFile);
            var child = ts.lastOrUndefined(children);
            if (!child) {
                return undefined;
            }
            return child.kind < 143 /* FirstNode */ ? child : child.getLastToken(sourceFile);
        };
        NodeObject.prototype.forEachChild = function (cbNode, cbNodeArray) {
            return ts.forEachChild(this, cbNode, cbNodeArray);
        };
        return NodeObject;
    }());
    var TokenOrIdentifierObject = /** @class */ (function () {
        function TokenOrIdentifierObject(pos, end) {
            // Set properties in same order as NodeObject
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.parent = undefined;
        }
        TokenOrIdentifierObject.prototype.getSourceFile = function () {
            return ts.getSourceFileOfNode(this);
        };
        TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
        };
        TokenOrIdentifierObject.prototype.getFullStart = function () {
            return this.pos;
        };
        TokenOrIdentifierObject.prototype.getEnd = function () {
            return this.end;
        };
        TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) {
            return this.getEnd() - this.getStart(sourceFile);
        };
        TokenOrIdentifierObject.prototype.getFullWidth = function () {
            return this.end - this.pos;
        };
        TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
            return this.getStart(sourceFile) - this.pos;
        };
        TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) {
            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
        };
        TokenOrIdentifierObject.prototype.getText = function (sourceFile) {
            return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
        };
        TokenOrIdentifierObject.prototype.getChildCount = function () {
            return 0;
        };
        TokenOrIdentifierObject.prototype.getChildAt = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.getChildren = function () {
            return ts.emptyArray;
        };
        TokenOrIdentifierObject.prototype.getFirstToken = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.getLastToken = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.forEachChild = function () {
            return undefined;
        };
        return TokenOrIdentifierObject;
    }());
    var SymbolObject = /** @class */ (function () {
        function SymbolObject(flags, name) {
            this.flags = flags;
            this.escapedName = name;
        }
        SymbolObject.prototype.getFlags = function () {
            return this.flags;
        };
        Object.defineProperty(SymbolObject.prototype, "name", {
            get: function () {
                return ts.symbolName(this);
            },
            enumerable: true,
            configurable: true
        });
        SymbolObject.prototype.getEscapedName = function () {
            return this.escapedName;
        };
        SymbolObject.prototype.getName = function () {
            return this.name;
        };
        SymbolObject.prototype.getDeclarations = function () {
            return this.declarations;
        };
        SymbolObject.prototype.getDocumentationComment = function () {
            if (this.documentationComment === undefined) {
                this.documentationComment = ts.JsDoc.getJsDocCommentsFromDeclarations(this.declarations);
            }
            return this.documentationComment;
        };
        SymbolObject.prototype.getJsDocTags = function () {
            if (this.tags === undefined) {
                this.tags = ts.JsDoc.getJsDocTagsFromDeclarations(this.declarations);
            }
            return this.tags;
        };
        return SymbolObject;
    }());
    var TokenObject = /** @class */ (function (_super) {
        __extends(TokenObject, _super);
        function TokenObject(kind, pos, end) {
            var _this = _super.call(this, pos, end) || this;
            _this.kind = kind;
            return _this;
        }
        return TokenObject;
    }(TokenOrIdentifierObject));
    var IdentifierObject = /** @class */ (function (_super) {
        __extends(IdentifierObject, _super);
        function IdentifierObject(_kind, pos, end) {
            return _super.call(this, pos, end) || this;
        }
        Object.defineProperty(IdentifierObject.prototype, "text", {
            get: function () {
                return ts.idText(this);
            },
            enumerable: true,
            configurable: true
        });
        return IdentifierObject;
    }(TokenOrIdentifierObject));
    IdentifierObject.prototype.kind = 71 /* Identifier */;
    var TypeObject = /** @class */ (function () {
        function TypeObject(checker, flags) {
            this.checker = checker;
            this.flags = flags;
        }
        TypeObject.prototype.getFlags = function () {
            return this.flags;
        };
        TypeObject.prototype.getSymbol = function () {
            return this.symbol;
        };
        TypeObject.prototype.getProperties = function () {
            return this.checker.getPropertiesOfType(this);
        };
        TypeObject.prototype.getProperty = function (propertyName) {
            return this.checker.getPropertyOfType(this, propertyName);
        };
        TypeObject.prototype.getApparentProperties = function () {
            return this.checker.getAugmentedPropertiesOfType(this);
        };
        TypeObject.prototype.getCallSignatures = function () {
            return this.checker.getSignaturesOfType(this, 0 /* Call */);
        };
        TypeObject.prototype.getConstructSignatures = function () {
            return this.checker.getSignaturesOfType(this, 1 /* Construct */);
        };
        TypeObject.prototype.getStringIndexType = function () {
            return this.checker.getIndexTypeOfType(this, 0 /* String */);
        };
        TypeObject.prototype.getNumberIndexType = function () {
            return this.checker.getIndexTypeOfType(this, 1 /* Number */);
        };
        TypeObject.prototype.getBaseTypes = function () {
            return this.flags & 32768 /* Object */ && this.objectFlags & (1 /* Class */ | 2 /* Interface */)
                ? this.checker.getBaseTypes(this)
                : undefined;
        };
        TypeObject.prototype.getNonNullableType = function () {
            return this.checker.getNonNullableType(this);
        };
        return TypeObject;
    }());
    var SignatureObject = /** @class */ (function () {
        function SignatureObject(checker) {
            this.checker = checker;
        }
        SignatureObject.prototype.getDeclaration = function () {
            return this.declaration;
        };
        SignatureObject.prototype.getTypeParameters = function () {
            return this.typeParameters;
        };
        SignatureObject.prototype.getParameters = function () {
            return this.parameters;
        };
        SignatureObject.prototype.getReturnType = function () {
            return this.checker.getReturnTypeOfSignature(this);
        };
        SignatureObject.prototype.getDocumentationComment = function () {
            if (this.documentationComment === undefined) {
                this.documentationComment = this.declaration ? ts.JsDoc.getJsDocCommentsFromDeclarations([this.declaration]) : [];
            }
            return this.documentationComment;
        };
        SignatureObject.prototype.getJsDocTags = function () {
            if (this.jsDocTags === undefined) {
                this.jsDocTags = this.declaration ? ts.JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : [];
            }
            return this.jsDocTags;
        };
        return SignatureObject;
    }());
    var SourceFileObject = /** @class */ (function (_super) {
        __extends(SourceFileObject, _super);
        function SourceFileObject(kind, pos, end) {
            return _super.call(this, kind, pos, end) || this;
        }
        SourceFileObject.prototype.update = function (newText, textChangeRange) {
            return ts.updateSourceFile(this, newText, textChangeRange);
        };
        SourceFileObject.prototype.getLineAndCharacterOfPosition = function (position) {
            return ts.getLineAndCharacterOfPosition(this, position);
        };
        SourceFileObject.prototype.getLineStarts = function () {
            return ts.getLineStarts(this);
        };
        SourceFileObject.prototype.getPositionOfLineAndCharacter = function (line, character) {
            return ts.getPositionOfLineAndCharacter(this, line, character);
        };
        SourceFileObject.prototype.getLineEndOfPosition = function (pos) {
            var line = this.getLineAndCharacterOfPosition(pos).line;
            var lineStarts = this.getLineStarts();
            var lastCharPos;
            if (line + 1 >= lineStarts.length) {
                lastCharPos = this.getEnd();
            }
            if (!lastCharPos) {
                lastCharPos = lineStarts[line + 1] - 1;
            }
            var fullText = this.getFullText();
            // if the new line is "\r\n", we should return the last non-new-line-character position
            return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos;
        };
        SourceFileObject.prototype.getNamedDeclarations = function () {
            if (!this.namedDeclarations) {
                this.namedDeclarations = this.computeNamedDeclarations();
            }
            return this.namedDeclarations;
        };
        SourceFileObject.prototype.computeNamedDeclarations = function () {
            var result = ts.createMultiMap();
            ts.forEachChild(this, visit);
            return result;
            function addDeclaration(declaration) {
                var name = getDeclarationName(declaration);
                if (name) {
                    result.add(name, declaration);
                }
            }
            function getDeclarations(name) {
                var declarations = result.get(name);
                if (!declarations) {
                    result.set(name, declarations = []);
                }
                return declarations;
            }
            function getDeclarationName(declaration) {
                var name = ts.getNameOfDeclaration(declaration);
                if (name) {
                    var result_9 = ts.getTextOfIdentifierOrLiteral(name);
                    if (result_9 !== undefined) {
                        return result_9;
                    }
                    if (name.kind === 144 /* ComputedPropertyName */) {
                        var expr = name.expression;
                        if (expr.kind === 179 /* PropertyAccessExpression */) {
                            return expr.name.text;
                        }
                        return ts.getTextOfIdentifierOrLiteral(expr);
                    }
                }
                return undefined;
            }
            function visit(node) {
                switch (node.kind) {
                    case 228 /* FunctionDeclaration */:
                    case 186 /* FunctionExpression */:
                    case 151 /* MethodDeclaration */:
                    case 150 /* MethodSignature */:
                        var functionDeclaration = node;
                        var declarationName = getDeclarationName(functionDeclaration);
                        if (declarationName) {
                            var declarations = getDeclarations(declarationName);
                            var lastDeclaration = ts.lastOrUndefined(declarations);
                            // Check whether this declaration belongs to an "overload group".
                            if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) {
                                // Overwrite the last declaration if it was an overload
                                // and this one is an implementation.
                                if (functionDeclaration.body && !lastDeclaration.body) {
                                    declarations[declarations.length - 1] = functionDeclaration;
                                }
                            }
                            else {
                                declarations.push(functionDeclaration);
                            }
                        }
                        ts.forEachChild(node, visit);
                        break;
                    case 229 /* ClassDeclaration */:
                    case 199 /* ClassExpression */:
                    case 230 /* InterfaceDeclaration */:
                    case 231 /* TypeAliasDeclaration */:
                    case 232 /* EnumDeclaration */:
                    case 233 /* ModuleDeclaration */:
                    case 237 /* ImportEqualsDeclaration */:
                    case 246 /* ExportSpecifier */:
                    case 242 /* ImportSpecifier */:
                    case 239 /* ImportClause */:
                    case 240 /* NamespaceImport */:
                    case 153 /* GetAccessor */:
                    case 154 /* SetAccessor */:
                    case 163 /* TypeLiteral */:
                        addDeclaration(node);
                        ts.forEachChild(node, visit);
                        break;
                    case 146 /* Parameter */:
                        // Only consider parameter properties
                        if (!ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                            break;
                        }
                    // falls through
                    case 226 /* VariableDeclaration */:
                    case 176 /* BindingElement */: {
                        var decl = node;
                        if (ts.isBindingPattern(decl.name)) {
                            ts.forEachChild(decl.name, visit);
                            break;
                        }
                        if (decl.initializer) {
                            visit(decl.initializer);
                        }
                    }
                    // falls through
                    case 264 /* EnumMember */:
                    case 149 /* PropertyDeclaration */:
                    case 148 /* PropertySignature */:
                        addDeclaration(node);
                        break;
                    case 244 /* ExportDeclaration */:
                        // Handle named exports case e.g.:
                        //    export {a, b as B} from "mod";
                        if (node.exportClause) {
                            ts.forEach(node.exportClause.elements, visit);
                        }
                        break;
                    case 238 /* ImportDeclaration */:
                        var importClause = node.importClause;
                        if (importClause) {
                            // Handle default import case e.g.:
                            //    import d from "mod";
                            if (importClause.name) {
                                addDeclaration(importClause);
                            }
                            // Handle named bindings in imports e.g.:
                            //    import * as NS from "mod";
                            //    import {a, b as B} from "mod";
                            if (importClause.namedBindings) {
                                if (importClause.namedBindings.kind === 240 /* NamespaceImport */) {
                                    addDeclaration(importClause.namedBindings);
                                }
                                else {
                                    ts.forEach(importClause.namedBindings.elements, visit);
                                }
                            }
                        }
                        break;
                    case 194 /* BinaryExpression */:
                        if (ts.getSpecialPropertyAssignmentKind(node) !== 0 /* None */) {
                            addDeclaration(node);
                        }
                    // falls through
                    default:
                        ts.forEachChild(node, visit);
                }
            }
        };
        return SourceFileObject;
    }(NodeObject));
    var SourceMapSourceObject = /** @class */ (function () {
        function SourceMapSourceObject(fileName, text, skipTrivia) {
            this.fileName = fileName;
            this.text = text;
            this.skipTrivia = skipTrivia;
        }
        SourceMapSourceObject.prototype.getLineAndCharacterOfPosition = function (pos) {
            return ts.getLineAndCharacterOfPosition(this, pos);
        };
        return SourceMapSourceObject;
    }());
    function getServicesObjectAllocator() {
        return {
            getNodeConstructor: function () { return NodeObject; },
            getTokenConstructor: function () { return TokenObject; },
            getIdentifierConstructor: function () { return IdentifierObject; },
            getSourceFileConstructor: function () { return SourceFileObject; },
            getSymbolConstructor: function () { return SymbolObject; },
            getTypeConstructor: function () { return TypeObject; },
            getSignatureConstructor: function () { return SignatureObject; },
            getSourceMapSourceConstructor: function () { return SourceMapSourceObject; },
        };
    }
    function toEditorSettings(optionsAsMap) {
        var allPropertiesAreCamelCased = true;
        for (var key in optionsAsMap) {
            if (ts.hasProperty(optionsAsMap, key) && !isCamelCase(key)) {
                allPropertiesAreCamelCased = false;
                break;
            }
        }
        if (allPropertiesAreCamelCased) {
            return optionsAsMap;
        }
        var settings = {};
        for (var key in optionsAsMap) {
            if (ts.hasProperty(optionsAsMap, key)) {
                var newKey = isCamelCase(key) ? key : key.charAt(0).toLowerCase() + key.substr(1);
                settings[newKey] = optionsAsMap[key];
            }
        }
        return settings;
    }
    ts.toEditorSettings = toEditorSettings;
    function isCamelCase(s) {
        return !s.length || s.charAt(0) === s.charAt(0).toLowerCase();
    }
    function displayPartsToString(displayParts) {
        if (displayParts) {
            return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join("");
        }
        return "";
    }
    ts.displayPartsToString = displayPartsToString;
    function getDefaultCompilerOptions() {
        // Always default to "ScriptTarget.ES5" for the language service
        return {
            target: 1 /* ES5 */,
            jsx: 1 /* Preserve */
        };
    }
    ts.getDefaultCompilerOptions = getDefaultCompilerOptions;
    function getSupportedCodeFixes() {
        return ts.codefix.getSupportedErrorCodes();
    }
    ts.getSupportedCodeFixes = getSupportedCodeFixes;
    // Cache host information about script Should be refreshed
    // at each language service public entry point, since we don't know when
    // the set of scripts handled by the host changes.
    var HostCache = /** @class */ (function () {
        function HostCache(host, getCanonicalFileName) {
            this.host = host;
            // script id => script index
            this.currentDirectory = host.getCurrentDirectory();
            this.fileNameToEntry = ts.createMap();
            // Initialize the list with the root file names
            var rootFileNames = host.getScriptFileNames();
            for (var _i = 0, rootFileNames_1 = rootFileNames; _i < rootFileNames_1.length; _i++) {
                var fileName = rootFileNames_1[_i];
                this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName));
            }
            // store the compilation settings
            this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions();
        }
        HostCache.prototype.compilationSettings = function () {
            return this._compilationSettings;
        };
        HostCache.prototype.createEntry = function (fileName, path) {
            var entry;
            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
            if (scriptSnapshot) {
                entry = {
                    hostFileName: fileName,
                    version: this.host.getScriptVersion(fileName),
                    scriptSnapshot: scriptSnapshot,
                    scriptKind: ts.getScriptKind(fileName, this.host)
                };
            }
            else {
                entry = fileName;
            }
            this.fileNameToEntry.set(path, entry);
            return entry;
        };
        HostCache.prototype.getEntryByPath = function (path) {
            return this.fileNameToEntry.get(path);
        };
        HostCache.prototype.getHostFileInformation = function (path) {
            var entry = this.fileNameToEntry.get(path);
            return !ts.isString(entry) ? entry : undefined;
        };
        HostCache.prototype.getOrCreateEntryByPath = function (fileName, path) {
            var info = this.getEntryByPath(path) || this.createEntry(fileName, path);
            return ts.isString(info) ? undefined : info;
        };
        HostCache.prototype.getRootFileNames = function () {
            return ts.arrayFrom(this.fileNameToEntry.values(), function (entry) {
                return ts.isString(entry) ? entry : entry.hostFileName;
            });
        };
        HostCache.prototype.getVersion = function (path) {
            var file = this.getHostFileInformation(path);
            return file && file.version;
        };
        HostCache.prototype.getScriptSnapshot = function (path) {
            var file = this.getHostFileInformation(path);
            return file && file.scriptSnapshot;
        };
        return HostCache;
    }());
    var SyntaxTreeCache = /** @class */ (function () {
        function SyntaxTreeCache(host) {
            this.host = host;
        }
        SyntaxTreeCache.prototype.getCurrentSourceFile = function (fileName) {
            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
            if (!scriptSnapshot) {
                // The host does not know about this file.
                throw new Error("Could not find file: '" + fileName + "'.");
            }
            var scriptKind = ts.getScriptKind(fileName, this.host);
            var version = this.host.getScriptVersion(fileName);
            var sourceFile;
            if (this.currentFileName !== fileName) {
                // This is a new file, just parse it
                sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, 5 /* Latest */, version, /*setNodeParents*/ true, scriptKind);
            }
            else if (this.currentFileVersion !== version) {
                // This is the same file, just a newer version. Incrementally parse the file.
                var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot);
                sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange);
            }
            if (sourceFile) {
                // All done, ensure state is up to date
                this.currentFileVersion = version;
                this.currentFileName = fileName;
                this.currentFileScriptSnapshot = scriptSnapshot;
                this.currentSourceFile = sourceFile;
            }
            return this.currentSourceFile;
        };
        return SyntaxTreeCache;
    }());
    function setSourceFileFields(sourceFile, scriptSnapshot, version) {
        sourceFile.version = version;
        sourceFile.scriptSnapshot = scriptSnapshot;
    }
    function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind) {
        var text = scriptSnapshot.getText(0, scriptSnapshot.getLength());
        var sourceFile = ts.createSourceFile(fileName, text, scriptTarget, setNodeParents, scriptKind);
        setSourceFileFields(sourceFile, scriptSnapshot, version);
        return sourceFile;
    }
    ts.createLanguageServiceSourceFile = createLanguageServiceSourceFile;
    ts.disableIncrementalParsing = false;
    function updateLanguageServiceSourceFile(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks) {
        // If we were given a text change range, and our version or open-ness changed, then
        // incrementally parse this file.
        if (textChangeRange) {
            if (version !== sourceFile.version) {
                // Once incremental parsing is ready, then just call into this function.
                if (!ts.disableIncrementalParsing) {
                    var newText = void 0;
                    // grab the fragment from the beginning of the original text to the beginning of the span
                    var prefix = textChangeRange.span.start !== 0
                        ? sourceFile.text.substr(0, textChangeRange.span.start)
                        : "";
                    // grab the fragment from the end of the span till the end of the original text
                    var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length
                        ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span))
                        : "";
                    if (textChangeRange.newLength === 0) {
                        // edit was a deletion - just combine prefix and suffix
                        newText = prefix && suffix ? prefix + suffix : prefix || suffix;
                    }
                    else {
                        // it was actual edit, fetch the fragment of new text that correspond to new span
                        var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength);
                        // combine prefix, changed text and suffix
                        newText = prefix && suffix
                            ? prefix + changedText + suffix
                            : prefix
                                ? (prefix + changedText)
                                : (changedText + suffix);
                    }
                    var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
                    setSourceFileFields(newSourceFile, scriptSnapshot, version);
                    // after incremental parsing nameTable might not be up-to-date
                    // drop it so it can be lazily recreated later
                    newSourceFile.nameTable = undefined;
                    // dispose all resources held by old script snapshot
                    if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) {
                        if (sourceFile.scriptSnapshot.dispose) {
                            sourceFile.scriptSnapshot.dispose();
                        }
                        sourceFile.scriptSnapshot = undefined;
                    }
                    return newSourceFile;
                }
            }
        }
        // Otherwise, just create a new source file.
        return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind);
    }
    ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile;
    var CancellationTokenObject = /** @class */ (function () {
        function CancellationTokenObject(cancellationToken) {
            this.cancellationToken = cancellationToken;
        }
        CancellationTokenObject.prototype.isCancellationRequested = function () {
            return this.cancellationToken && this.cancellationToken.isCancellationRequested();
        };
        CancellationTokenObject.prototype.throwIfCancellationRequested = function () {
            if (this.isCancellationRequested()) {
                throw new ts.OperationCanceledException();
            }
        };
        return CancellationTokenObject;
    }());
    /* @internal */
    /** A cancellation that throttles calls to the host */
    var ThrottledCancellationToken = /** @class */ (function () {
        function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) {
            if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; }
            this.hostCancellationToken = hostCancellationToken;
            this.throttleWaitMilliseconds = throttleWaitMilliseconds;
            // Store when we last tried to cancel.  Checking cancellation can be expensive (as we have
            // to marshall over to the host layer).  So we only bother actually checking once enough
            // time has passed.
            this.lastCancellationCheckTime = 0;
        }
        ThrottledCancellationToken.prototype.isCancellationRequested = function () {
            var time = ts.timestamp();
            var duration = Math.abs(time - this.lastCancellationCheckTime);
            if (duration >= this.throttleWaitMilliseconds) {
                // Check no more than once every throttle wait milliseconds
                this.lastCancellationCheckTime = time;
                return this.hostCancellationToken.isCancellationRequested();
            }
            return false;
        };
        ThrottledCancellationToken.prototype.throwIfCancellationRequested = function () {
            if (this.isCancellationRequested()) {
                throw new ts.OperationCanceledException();
            }
        };
        return ThrottledCancellationToken;
    }());
    ts.ThrottledCancellationToken = ThrottledCancellationToken;
    function createLanguageService(host, documentRegistry) {
        if (documentRegistry === void 0) { documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); }
        var syntaxTreeCache = new SyntaxTreeCache(host);
        ruleProvider = ruleProvider || new ts.formatting.RulesProvider();
        var program;
        var lastProjectVersion;
        var lastTypesRootVersion = 0;
        var useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames();
        var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
        var currentDirectory = host.getCurrentDirectory();
        // Check if the localized messages json is set, otherwise query the host for it
        if (!ts.localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) {
            ts.localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages();
        }
        function log(message) {
            if (host.log) {
                host.log(message);
            }
        }
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitivefileNames);
        function getValidSourceFile(fileName) {
            var sourceFile = program.getSourceFile(fileName);
            if (!sourceFile) {
                throw new Error("Could not find file: '" + fileName + "'.");
            }
            return sourceFile;
        }
        function getRuleProvider(options) {
            ruleProvider.ensureUpToDate(options);
            return ruleProvider;
        }
        function synchronizeHostData() {
            // perform fast check if host supports it
            if (host.getProjectVersion) {
                var hostProjectVersion = host.getProjectVersion();
                if (hostProjectVersion) {
                    if (lastProjectVersion === hostProjectVersion && !host.hasChangedAutomaticTypeDirectiveNames) {
                        return;
                    }
                    lastProjectVersion = hostProjectVersion;
                }
            }
            var typeRootsVersion = host.getTypeRootsVersion ? host.getTypeRootsVersion() : 0;
            if (lastTypesRootVersion !== typeRootsVersion) {
                log("TypeRoots version has changed; provide new program");
                program = undefined;
                lastTypesRootVersion = typeRootsVersion;
            }
            // Get a fresh cache of the host information
            var hostCache = new HostCache(host, getCanonicalFileName);
            var rootFileNames = hostCache.getRootFileNames();
            var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
            // If the program is already up-to-date, we can reuse it
            if (ts.isProgramUptoDate(program, rootFileNames, hostCache.compilationSettings(), function (path) { return hostCache.getVersion(path); }, fileExists, hasInvalidatedResolution, host.hasChangedAutomaticTypeDirectiveNames)) {
                return;
            }
            // IMPORTANT - It is critical from this moment onward that we do not check
            // cancellation tokens.  We are about to mutate source files from a previous program
            // instance.  If we cancel midway through, we may end up in an inconsistent state where
            // the program points to old source files that have been invalidated because of
            // incremental parsing.
            var newSettings = hostCache.compilationSettings();
            // Now create a new compiler
            var compilerHost = {
                getSourceFile: getOrCreateSourceFile,
                getSourceFileByPath: getOrCreateSourceFileByPath,
                getCancellationToken: function () { return cancellationToken; },
                getCanonicalFileName: getCanonicalFileName,
                useCaseSensitiveFileNames: function () { return useCaseSensitivefileNames; },
                getNewLine: function () { return ts.getNewLineCharacter(newSettings, { newLine: ts.getNewLineOrDefaultFromHost(host) }); },
                getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
                writeFile: ts.noop,
                getCurrentDirectory: function () { return currentDirectory; },
                fileExists: fileExists,
                readFile: function (fileName) {
                    // stub missing host functionality
                    var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
                    var entry = hostCache.getEntryByPath(path);
                    if (entry) {
                        return ts.isString(entry) ? undefined : entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength());
                    }
                    return host.readFile && host.readFile(fileName);
                },
                directoryExists: function (directoryName) {
                    return ts.directoryProbablyExists(directoryName, host);
                },
                getDirectories: function (path) {
                    return host.getDirectories ? host.getDirectories(path) : [];
                },
                onReleaseOldSourceFile: onReleaseOldSourceFile,
                hasInvalidatedResolution: hasInvalidatedResolution,
                hasChangedAutomaticTypeDirectiveNames: host.hasChangedAutomaticTypeDirectiveNames
            };
            if (host.trace) {
                compilerHost.trace = function (message) { return host.trace(message); };
            }
            if (host.resolveModuleNames) {
                compilerHost.resolveModuleNames = function (moduleNames, containingFile, reusedNames) { return host.resolveModuleNames(moduleNames, containingFile, reusedNames); };
            }
            if (host.resolveTypeReferenceDirectives) {
                compilerHost.resolveTypeReferenceDirectives = function (typeReferenceDirectiveNames, containingFile) {
                    return host.resolveTypeReferenceDirectives(typeReferenceDirectiveNames, containingFile);
                };
            }
            var documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
            program = ts.createProgram(rootFileNames, newSettings, compilerHost, program);
            // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point.
            // It needs to be cleared to allow all collected snapshots to be released
            hostCache = undefined;
            // Make sure all the nodes in the program are both bound, and have their parent
            // pointers set property.
            program.getTypeChecker();
            return;
            function fileExists(fileName) {
                var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
                var entry = hostCache.getEntryByPath(path);
                return entry ?
                    !ts.isString(entry) :
                    (host.fileExists && host.fileExists(fileName));
            }
            // Release any files we have acquired in the old program but are
            // not part of the new program.
            function onReleaseOldSourceFile(oldSourceFile, oldOptions) {
                var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions);
                documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey);
            }
            function getOrCreateSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
                return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile);
            }
            function getOrCreateSourceFileByPath(fileName, path, _languageVersion, _onError, shouldCreateNewSourceFile) {
                ts.Debug.assert(hostCache !== undefined);
                // The program is asking for this file, check first if the host can locate it.
                // If the host can not locate the file, then it does not exist. return undefined
                // to the program to allow reporting of errors for missing files.
                var hostFileInformation = hostCache.getOrCreateEntryByPath(fileName, path);
                if (!hostFileInformation) {
                    return undefined;
                }
                // Check if the language version has changed since we last created a program; if they are the same,
                // it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile
                // can not be reused. we have to dump all syntax trees and create new ones.
                if (!shouldCreateNewSourceFile) {
                    // Check if the old program had this file already
                    var oldSourceFile = program && program.getSourceFileByPath(path);
                    if (oldSourceFile) {
                        // We already had a source file for this file name.  Go to the registry to
                        // ensure that we get the right up to date version of it.  We need this to
                        // address the following race-condition.  Specifically, say we have the following:
                        //
                        //      LS1
                        //          \
                        //           DocumentRegistry
                        //          /
                        //      LS2
                        //
                        // Each LS has a reference to file 'foo.ts' at version 1.  LS2 then updates
                        // it's version of 'foo.ts' to version 2.  This will cause LS2 and the
                        // DocumentRegistry to have version 2 of the document.  HOwever, LS1 will
                        // have version 1.  And *importantly* this source file will be *corrupt*.
                        // The act of creating version 2 of the file irrevocably damages the version
                        // 1 file.
                        //
                        // So, later when we call into LS1, we need to make sure that it doesn't use
                        // it's source file any more, and instead defers to DocumentRegistry to get
                        // either version 1, version 2 (or some other version) depending on what the
                        // host says should be used.
                        // We do not support the scenario where a host can modify a registered
                        // file's script kind, i.e. in one project some file is treated as ".ts"
                        // and in another as ".js"
                        ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path);
                        return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
                    }
                    // We didn't already have the file.  Fall through and acquire it from the registry.
                }
                // Could not find this file in the old program, create a new SourceFile for it.
                return documentRegistry.acquireDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
            }
        }
        function getProgram() {
            synchronizeHostData();
            return program;
        }
        function cleanupSemanticCache() {
            program = undefined;
        }
        function dispose() {
            if (program) {
                ts.forEach(program.getSourceFiles(), function (f) {
                    return documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions());
                });
                program = undefined;
            }
            host = undefined;
        }
        /// Diagnostics
        function getSyntacticDiagnostics(fileName) {
            synchronizeHostData();
            return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice();
        }
        /**
         * getSemanticDiagnostics return array of Diagnostics. If '-d' is not enabled, only report semantic errors
         * If '-d' enabled, report both semantic and emitter errors
         */
        function getSemanticDiagnostics(fileName) {
            synchronizeHostData();
            var targetSourceFile = getValidSourceFile(fileName);
            // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
            // Therefore only get diagnostics for given file.
            var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
            if (!program.getCompilerOptions().declaration) {
                return semanticDiagnostics.slice();
            }
            // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
            var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
            return semanticDiagnostics.concat(declarationDiagnostics);
        }
        function getCompilerOptionsDiagnostics() {
            synchronizeHostData();
            return program.getOptionsDiagnostics(cancellationToken).concat(program.getGlobalDiagnostics(cancellationToken));
        }
        function getCompletionsAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.Completions.getCompletionsAtPosition(host, program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, program.getSourceFiles());
        }
        function getCompletionEntryDetails(fileName, position, name, formattingOptions, source) {
            synchronizeHostData();
            var ruleProvider = formattingOptions ? getRuleProvider(formattingOptions) : undefined;
            return ts.Completions.getCompletionEntryDetails(program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, { name: name, source: source }, program.getSourceFiles(), host, ruleProvider);
        }
        function getCompletionEntrySymbol(fileName, position, name, source) {
            synchronizeHostData();
            return ts.Completions.getCompletionEntrySymbol(program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, { name: name, source: source }, program.getSourceFiles());
        }
        function getQuickInfoAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
            if (node === sourceFile) {
                return undefined;
            }
            if (ts.isLabelName(node)) {
                return undefined;
            }
            var typeChecker = program.getTypeChecker();
            var symbol = getSymbolAtLocationForQuickInfo(node, typeChecker);
            if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
                // Try getting just type at this position and show
                switch (node.kind) {
                    case 71 /* Identifier */:
                    case 179 /* PropertyAccessExpression */:
                    case 143 /* QualifiedName */:
                    case 99 /* ThisKeyword */:
                    case 169 /* ThisType */:
                    case 97 /* SuperKeyword */:
                        // For the identifiers/this/super etc get the type at position
                        var type = typeChecker.getTypeAtLocation(node);
                        if (type) {
                            return {
                                kind: "" /* unknown */,
                                kindModifiers: "" /* none */,
                                textSpan: ts.createTextSpan(node.getStart(), node.getWidth()),
                                displayParts: ts.typeToDisplayParts(typeChecker, type, ts.getContainerNode(node)),
                                documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined,
                                tags: type.symbol ? type.symbol.getJsDocTags() : undefined
                            };
                        }
                }
                return undefined;
            }
            var displayPartsDocumentationsAndKind = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, ts.getContainerNode(node), node);
            return {
                kind: displayPartsDocumentationsAndKind.symbolKind,
                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
                textSpan: ts.createTextSpan(node.getStart(), node.getWidth()),
                displayParts: displayPartsDocumentationsAndKind.displayParts,
                documentation: displayPartsDocumentationsAndKind.documentation,
                tags: displayPartsDocumentationsAndKind.tags
            };
        }
        function getSymbolAtLocationForQuickInfo(node, checker) {
            if ((ts.isIdentifier(node) || ts.isStringLiteral(node))
                && ts.isPropertyAssignment(node.parent)
                && node.parent.name === node) {
                var type = checker.getContextualType(node.parent.parent);
                if (type) {
                    var property = checker.getPropertyOfType(type, ts.getTextOfIdentifierOrLiteral(node));
                    if (property) {
                        return property;
                    }
                }
            }
            return checker.getSymbolAtLocation(node);
        }
        /// Goto definition
        function getDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position);
        }
        function getTypeDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position);
        }
        /// Goto implementation
        function getImplementationAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
        }
        /// References and Occurrences
        function getOccurrencesAtPosition(fileName, position) {
            var results = getOccurrencesAtPositionCore(fileName, position);
            if (results) {
                var sourceFile_1 = getCanonicalFileName(ts.normalizeSlashes(fileName));
                // Get occurrences only supports reporting occurrences for the file queried.  So
                // filter down to that list.
                results = ts.filter(results, function (r) { return getCanonicalFileName(ts.normalizeSlashes(r.fileName)) === sourceFile_1; });
            }
            return results;
        }
        function getDocumentHighlights(fileName, position, filesToSearch) {
            synchronizeHostData();
            var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); });
            var sourceFile = getValidSourceFile(fileName);
            return ts.DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch);
        }
        function getOccurrencesAtPositionCore(fileName, position) {
            return convertDocumentHighlights(getDocumentHighlights(fileName, position, [fileName]));
            function convertDocumentHighlights(documentHighlights) {
                if (!documentHighlights) {
                    return undefined;
                }
                var result = [];
                for (var _i = 0, documentHighlights_1 = documentHighlights; _i < documentHighlights_1.length; _i++) {
                    var entry = documentHighlights_1[_i];
                    for (var _a = 0, _b = entry.highlightSpans; _a < _b.length; _a++) {
                        var highlightSpan = _b[_a];
                        result.push({
                            fileName: entry.fileName,
                            textSpan: highlightSpan.textSpan,
                            isWriteAccess: highlightSpan.kind === "writtenReference" /* writtenReference */,
                            isDefinition: false,
                            isInString: highlightSpan.isInString,
                        });
                    }
                }
                return result;
            }
        }
        function findRenameLocations(fileName, position, findInStrings, findInComments) {
            return getReferences(fileName, position, { findInStrings: findInStrings, findInComments: findInComments, isForRename: true });
        }
        function getReferencesAtPosition(fileName, position) {
            return getReferences(fileName, position);
        }
        function getReferences(fileName, position, options) {
            synchronizeHostData();
            // Exclude default library when renaming as commonly user don't want to change that file.
            var sourceFiles = [];
            if (options && options.isForRename) {
                for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                    var sourceFile = _a[_i];
                    if (!program.isSourceFileDefaultLibrary(sourceFile)) {
                        sourceFiles.push(sourceFile);
                    }
                }
            }
            else {
                sourceFiles = program.getSourceFiles().slice();
            }
            return ts.FindAllReferences.findReferencedEntries(program, cancellationToken, sourceFiles, getValidSourceFile(fileName), position, options);
        }
        function findReferences(fileName, position) {
            synchronizeHostData();
            return ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
        }
        /// NavigateTo
        function getNavigateToItems(searchValue, maxResultCount, fileName, excludeDtsFiles) {
            synchronizeHostData();
            var sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles();
            return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles);
        }
        function getEmitOutput(fileName, emitOnlyDtsFiles) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var customTransformers = host.getCustomTransformers && host.getCustomTransformers();
            return ts.getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers);
        }
        // Signature help
        /**
         * This is a semantic operation.
         */
        function getSignatureHelpItems(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken);
        }
        /// Syntactic features
        function getNonBoundSourceFile(fileName) {
            return syntaxTreeCache.getCurrentSourceFile(fileName);
        }
        function getSourceFile(fileName) {
            return getNonBoundSourceFile(fileName);
        }
        function getNameOrDottedNameSpan(fileName, startPos, _endPos) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Get node at the location
            var node = ts.getTouchingPropertyName(sourceFile, startPos, /*includeJsDocComment*/ false);
            if (node === sourceFile) {
                return;
            }
            switch (node.kind) {
                case 179 /* PropertyAccessExpression */:
                case 143 /* QualifiedName */:
                case 9 /* StringLiteral */:
                case 86 /* FalseKeyword */:
                case 101 /* TrueKeyword */:
                case 95 /* NullKeyword */:
                case 97 /* SuperKeyword */:
                case 99 /* ThisKeyword */:
                case 169 /* ThisType */:
                case 71 /* Identifier */:
                    break;
                // Cant create the text span
                default:
                    return;
            }
            var nodeForStartPos = node;
            while (true) {
                if (ts.isRightSideOfPropertyAccess(nodeForStartPos) || ts.isRightSideOfQualifiedName(nodeForStartPos)) {
                    // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node
                    nodeForStartPos = nodeForStartPos.parent;
                }
                else if (ts.isNameOfModuleDeclaration(nodeForStartPos)) {
                    // If this is name of a module declarations, check if this is right side of dotted module name
                    // If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of
                    // Then this name is name from dotted module
                    if (nodeForStartPos.parent.parent.kind === 233 /* ModuleDeclaration */ &&
                        nodeForStartPos.parent.parent.body === nodeForStartPos.parent) {
                        // Use parent module declarations name for start pos
                        nodeForStartPos = nodeForStartPos.parent.parent.name;
                    }
                    else {
                        // We have to use this name for start pos
                        break;
                    }
                }
                else {
                    // Is not a member expression so we have found the node for start pos
                    break;
                }
            }
            return ts.createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd());
        }
        function getBreakpointStatementAtPosition(fileName, position) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position);
        }
        function getNavigationBarItems(fileName) {
            return ts.NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
        }
        function getNavigationTree(fileName) {
            return ts.NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
        }
        function isTsOrTsxFile(fileName) {
            var kind = ts.getScriptKind(fileName, host);
            return kind === 3 /* TS */ || kind === 4 /* TSX */;
        }
        function getSemanticClassifications(fileName, span) {
            if (!isTsOrTsxFile(fileName)) {
                // do not run semantic classification on non-ts-or-tsx files
                return [];
            }
            synchronizeHostData();
            return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
        }
        function getEncodedSemanticClassifications(fileName, span) {
            if (!isTsOrTsxFile(fileName)) {
                // do not run semantic classification on non-ts-or-tsx files
                return { spans: [], endOfLineState: 0 /* None */ };
            }
            synchronizeHostData();
            return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
        }
        function getSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
        }
        function getEncodedSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
        }
        function getOutliningSpans(fileName) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
        }
        function getBraceMatchingAtPosition(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var result = [];
            var token = ts.getTouchingToken(sourceFile, position, /*includeJsDocComment*/ false);
            if (token.getStart(sourceFile) === position) {
                var matchKind = getMatchingTokenKind(token);
                // Ensure that there is a corresponding token to match ours.
                if (matchKind) {
                    var parentElement = token.parent;
                    var childNodes = parentElement.getChildren(sourceFile);
                    for (var _i = 0, childNodes_1 = childNodes; _i < childNodes_1.length; _i++) {
                        var current = childNodes_1[_i];
                        if (current.kind === matchKind) {
                            var range1 = ts.createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile));
                            var range2 = ts.createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile));
                            // We want to order the braces when we return the result.
                            if (range1.start < range2.start) {
                                result.push(range1, range2);
                            }
                            else {
                                result.push(range2, range1);
                            }
                            break;
                        }
                    }
                }
            }
            return result;
            function getMatchingTokenKind(token) {
                switch (token.kind) {
                    case 17 /* OpenBraceToken */: return 18 /* CloseBraceToken */;
                    case 19 /* OpenParenToken */: return 20 /* CloseParenToken */;
                    case 21 /* OpenBracketToken */: return 22 /* CloseBracketToken */;
                    case 27 /* LessThanToken */: return 29 /* GreaterThanToken */;
                    case 18 /* CloseBraceToken */: return 17 /* OpenBraceToken */;
                    case 20 /* CloseParenToken */: return 19 /* OpenParenToken */;
                    case 22 /* CloseBracketToken */: return 21 /* OpenBracketToken */;
                    case 29 /* GreaterThanToken */: return 27 /* LessThanToken */;
                }
                return undefined;
            }
        }
        function getIndentationAtPosition(fileName, position, editorOptions) {
            var start = ts.timestamp();
            var settings = toEditorSettings(editorOptions);
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            log("getIndentationAtPosition: getCurrentSourceFile: " + (ts.timestamp() - start));
            start = ts.timestamp();
            var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, settings);
            log("getIndentationAtPosition: computeIndentation  : " + (ts.timestamp() - start));
            return result;
        }
        function getFormattingEditsForRange(fileName, start, end, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var settings = toEditorSettings(options);
            return ts.formatting.formatSelection(start, end, sourceFile, getRuleProvider(settings), settings);
        }
        function getFormattingEditsForDocument(fileName, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var settings = toEditorSettings(options);
            return ts.formatting.formatDocument(sourceFile, getRuleProvider(settings), settings);
        }
        function getFormattingEditsAfterKeystroke(fileName, position, key, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var settings = toEditorSettings(options);
            if (!ts.isInComment(sourceFile, position)) {
                if (key === "{") {
                    return ts.formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings);
                }
                else if (key === "}") {
                    return ts.formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings);
                }
                else if (key === ";") {
                    return ts.formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(settings), settings);
                }
                else if (key === "\n") {
                    return ts.formatting.formatOnEnter(position, sourceFile, getRuleProvider(settings), settings);
                }
            }
            return [];
        }
        function getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var span = ts.createTextSpanFromBounds(start, end);
            var newLineCharacter = ts.getNewLineOrDefaultFromHost(host);
            var rulesProvider = getRuleProvider(formatOptions);
            return ts.flatMap(ts.deduplicate(errorCodes), function (errorCode) {
                cancellationToken.throwIfCancellationRequested();
                return ts.codefix.getFixes({ errorCode: errorCode, sourceFile: sourceFile, span: span, program: program, newLineCharacter: newLineCharacter, host: host, cancellationToken: cancellationToken, rulesProvider: rulesProvider });
            });
        }
        function applyCodeActionCommand(fileName, action) {
            fileName = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            switch (action.type) {
                case "install package":
                    return host.installPackage
                        ? host.installPackage({ fileName: fileName, packageName: action.packageName })
                        : Promise.reject("Host does not implement `installPackage`");
                default:
                    ts.Debug.fail();
            }
        }
        function getDocCommentTemplateAtPosition(fileName, position) {
            return ts.JsDoc.getDocCommentTemplateAtPosition(ts.getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position);
        }
        function isValidBraceCompletionAtPosition(fileName, position, openingBrace) {
            // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
            // expensive to do during typing scenarios
            // i.e. whether we're dealing with:
            //      var x = new foo<| ( with class foo<T>{} )
            // or
            //      var y = 3 <|
            if (openingBrace === 60 /* lessThan */) {
                return false;
            }
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Check if in a context where we don't want to perform any insertion
            if (ts.isInString(sourceFile, position)) {
                return false;
            }
            if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) {
                return openingBrace === 123 /* openBrace */;
            }
            if (ts.isInTemplateString(sourceFile, position)) {
                return false;
            }
            switch (openingBrace) {
                case 39 /* singleQuote */:
                case 34 /* doubleQuote */:
                case 96 /* backtick */:
                    return !ts.isInComment(sourceFile, position);
            }
            return true;
        }
        function getSpanOfEnclosingComment(fileName, position, onlyMultiLine) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine);
            return range && ts.createTextSpanFromRange(range);
        }
        function getTodoComments(fileName, descriptors) {
            // Note: while getting todo comments seems like a syntactic operation, we actually
            // treat it as a semantic operation here.  This is because we expect our host to call
            // this on every single file.  If we treat this syntactically, then that will cause
            // us to populate and throw away the tree in our syntax tree cache for each file.  By
            // treating this as a semantic operation, we can access any tree without throwing
            // anything away.
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            cancellationToken.throwIfCancellationRequested();
            var fileContents = sourceFile.text;
            var result = [];
            // Exclude node_modules files as we don't want to show the todos of external libraries.
            if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) {
                var regExp = getTodoCommentsRegExp();
                var matchArray = void 0;
                while (matchArray = regExp.exec(fileContents)) {
                    cancellationToken.throwIfCancellationRequested();
                    // If we got a match, here is what the match array will look like.  Say the source text is:
                    //
                    //      "    // hack   1"
                    //
                    // The result array with the regexp:    will be:
                    //
                    //      ["// hack   1", "// ", "hack   1", undefined, "hack"]
                    //
                    // Here are the relevant capture groups:
                    //  0) The full match for the entire regexp.
                    //  1) The preamble to the message portion.
                    //  2) The message portion.
                    //  3...N) The descriptor that was matched - by index.  'undefined' for each
                    //         descriptor that didn't match.  an actual value if it did match.
                    //
                    //  i.e. 'undefined' in position 3 above means TODO(jason) didn't match.
                    //       "hack"      in position 4 means HACK did match.
                    var firstDescriptorCaptureIndex = 3;
                    ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex);
                    var preamble = matchArray[1];
                    var matchPosition = matchArray.index + preamble.length;
                    // OK, we have found a match in the file.  This is only an acceptable match if
                    // it is contained within a comment.
                    if (!ts.isInComment(sourceFile, matchPosition)) {
                        continue;
                    }
                    var descriptor = undefined;
                    for (var i = 0; i < descriptors.length; i++) {
                        if (matchArray[i + firstDescriptorCaptureIndex]) {
                            descriptor = descriptors[i];
                        }
                    }
                    ts.Debug.assert(descriptor !== undefined);
                    // We don't want to match something like 'TODOBY', so we make sure a non
                    // letter/digit follows the match.
                    if (isLetterOrDigit(fileContents.charCodeAt(matchPosition + descriptor.text.length))) {
                        continue;
                    }
                    var message = matchArray[2];
                    result.push({ descriptor: descriptor, message: message, position: matchPosition });
                }
            }
            return result;
            function escapeRegExp(str) {
                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            }
            function getTodoCommentsRegExp() {
                // NOTE: ?:  means 'non-capture group'.  It allows us to have groups without having to
                // filter them out later in the final result array.
                // TODO comments can appear in one of the following forms:
                //
                //  1)      // TODO     or  /////////// TODO
                //
                //  2)      /* TODO     or  /********** TODO
                //
                //  3)      /*
                //           *   TODO
                //           */
                //
                // The following three regexps are used to match the start of the text up to the TODO
                // comment portion.
                var singleLineCommentStart = /(?:\/\/+\s*)/.source;
                var multiLineCommentStart = /(?:\/\*+\s*)/.source;
                var anyNumberOfSpacesAndAsterisksAtStartOfLine = /(?:^(?:\s|\*)*)/.source;
                // Match any of the above three TODO comment start regexps.
                // Note that the outermost group *is* a capture group.  We want to capture the preamble
                // so that we can determine the starting position of the TODO comment match.
                var preamble = "(" + anyNumberOfSpacesAndAsterisksAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")";
                // Takes the descriptors and forms a regexp that matches them as if they were literals.
                // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be:
                //
                //      (?:(TODO\(jason\))|(HACK))
                //
                // Note that the outermost group is *not* a capture group, but the innermost groups
                // *are* capture groups.  By capturing the inner literals we can determine after
                // matching which descriptor we are dealing with.
                var literals = "(?:" + ts.map(descriptors, function (d) { return "(" + escapeRegExp(d.text) + ")"; }).join("|") + ")";
                // After matching a descriptor literal, the following regexp matches the rest of the
                // text up to the end of the line (or */).
                var endOfLineOrEndOfComment = /(?:$|\*\/)/.source;
                var messageRemainder = /(?:.*?)/.source;
                // This is the portion of the match we'll return as part of the TODO comment result. We
                // match the literal portion up to the end of the line or end of comment.
                var messagePortion = "(" + literals + messageRemainder + ")";
                var regExpString = preamble + messagePortion + endOfLineOrEndOfComment;
                // The final regexp will look like this:
                // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim
                // The flags of the regexp are important here.
                //  'g' is so that we are doing a global search and can find matches several times
                //  in the input.
                //
                //  'i' is for case insensitivity (We do this to match C# TODO comment code).
                //
                //  'm' is so we can find matches in a multi-line input.
                return new RegExp(regExpString, "gim");
            }
            function isLetterOrDigit(char) {
                return (char >= 97 /* a */ && char <= 122 /* z */) ||
                    (char >= 65 /* A */ && char <= 90 /* Z */) ||
                    (char >= 48 /* _0 */ && char <= 57 /* _9 */);
            }
            function isNodeModulesFile(path) {
                var node_modulesFolderName = "/node_modules/";
                return ts.stringContains(path, node_modulesFolderName);
            }
        }
        function getRenameInfo(fileName, position) {
            synchronizeHostData();
            var defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings());
            return ts.Rename.getRenameInfo(program.getTypeChecker(), defaultLibFileName, getCanonicalFileName, getValidSourceFile(fileName), position);
        }
        function getRefactorContext(file, positionOrRange, formatOptions) {
            var _a = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end], startPosition = _a[0], endPosition = _a[1];
            return {
                file: file,
                startPosition: startPosition,
                endPosition: endPosition,
                program: getProgram(),
                newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(),
                host: host,
                rulesProvider: getRuleProvider(formatOptions),
                cancellationToken: cancellationToken,
            };
        }
        function getApplicableRefactors(fileName, positionOrRange) {
            synchronizeHostData();
            var file = getValidSourceFile(fileName);
            return ts.refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange));
        }
        function getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName) {
            synchronizeHostData();
            var file = getValidSourceFile(fileName);
            return ts.refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, formatOptions), refactorName, actionName);
        }
        return {
            dispose: dispose,
            cleanupSemanticCache: cleanupSemanticCache,
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
            getSyntacticClassifications: getSyntacticClassifications,
            getSemanticClassifications: getSemanticClassifications,
            getEncodedSyntacticClassifications: getEncodedSyntacticClassifications,
            getEncodedSemanticClassifications: getEncodedSemanticClassifications,
            getCompletionsAtPosition: getCompletionsAtPosition,
            getCompletionEntryDetails: getCompletionEntryDetails,
            getCompletionEntrySymbol: getCompletionEntrySymbol,
            getSignatureHelpItems: getSignatureHelpItems,
            getQuickInfoAtPosition: getQuickInfoAtPosition,
            getDefinitionAtPosition: getDefinitionAtPosition,
            getImplementationAtPosition: getImplementationAtPosition,
            getTypeDefinitionAtPosition: getTypeDefinitionAtPosition,
            getReferencesAtPosition: getReferencesAtPosition,
            findReferences: findReferences,
            getOccurrencesAtPosition: getOccurrencesAtPosition,
            getDocumentHighlights: getDocumentHighlights,
            getNameOrDottedNameSpan: getNameOrDottedNameSpan,
            getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
            getNavigateToItems: getNavigateToItems,
            getRenameInfo: getRenameInfo,
            findRenameLocations: findRenameLocations,
            getNavigationBarItems: getNavigationBarItems,
            getNavigationTree: getNavigationTree,
            getOutliningSpans: getOutliningSpans,
            getTodoComments: getTodoComments,
            getBraceMatchingAtPosition: getBraceMatchingAtPosition,
            getIndentationAtPosition: getIndentationAtPosition,
            getFormattingEditsForRange: getFormattingEditsForRange,
            getFormattingEditsForDocument: getFormattingEditsForDocument,
            getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
            getDocCommentTemplateAtPosition: getDocCommentTemplateAtPosition,
            isValidBraceCompletionAtPosition: isValidBraceCompletionAtPosition,
            getSpanOfEnclosingComment: getSpanOfEnclosingComment,
            getCodeFixesAtPosition: getCodeFixesAtPosition,
            applyCodeActionCommand: applyCodeActionCommand,
            getEmitOutput: getEmitOutput,
            getNonBoundSourceFile: getNonBoundSourceFile,
            getSourceFile: getSourceFile,
            getProgram: getProgram,
            getApplicableRefactors: getApplicableRefactors,
            getEditsForRefactor: getEditsForRefactor,
        };
    }
    ts.createLanguageService = createLanguageService;
    /* @internal */
    /** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */
    function getNameTable(sourceFile) {
        if (!sourceFile.nameTable) {
            initializeNameTable(sourceFile);
        }
        return sourceFile.nameTable;
    }
    ts.getNameTable = getNameTable;
    function initializeNameTable(sourceFile) {
        var nameTable = sourceFile.nameTable = ts.createUnderscoreEscapedMap();
        sourceFile.forEachChild(function walk(node) {
            if (ts.isIdentifier(node) && node.escapedText || ts.isStringOrNumericLiteral(node) && literalIsName(node)) {
                var text = ts.getEscapedTextOfIdentifierOrLiteral(node);
                nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
            }
            ts.forEachChild(node, walk);
            if (ts.hasJSDocNodes(node)) {
                for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                    var jsDoc = _a[_i];
                    ts.forEachChild(jsDoc, walk);
                }
            }
        });
    }
    /**
     * We want to store any numbers/strings if they were a name that could be
     * related to a declaration.  So, if we have 'import x = require("something")'
     * then we want 'something' to be in the name table.  Similarly, if we have
     * "a['propname']" then we want to store "propname" in the name table.
     */
    function literalIsName(node) {
        return ts.isDeclarationName(node) ||
            node.parent.kind === 248 /* ExternalModuleReference */ ||
            isArgumentOfElementAccessExpression(node) ||
            ts.isLiteralComputedPropertyDeclarationName(node);
    }
    function isObjectLiteralElement(node) {
        switch (node.kind) {
            case 253 /* JsxAttribute */:
            case 255 /* JsxSpreadAttribute */:
            case 261 /* PropertyAssignment */:
            case 262 /* ShorthandPropertyAssignment */:
            case 151 /* MethodDeclaration */:
            case 153 /* GetAccessor */:
            case 154 /* SetAccessor */:
                return true;
        }
        return false;
    }
    /**
     * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
     */
    /* @internal */
    function getContainingObjectLiteralElement(node) {
        switch (node.kind) {
            case 9 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                if (node.parent.kind === 144 /* ComputedPropertyName */) {
                    return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
                }
            // falls through
            case 71 /* Identifier */:
                return isObjectLiteralElement(node.parent) &&
                    (node.parent.parent.kind === 178 /* ObjectLiteralExpression */ || node.parent.parent.kind === 254 /* JsxAttributes */) &&
                    node.parent.name === node ? node.parent : undefined;
        }
        return undefined;
    }
    ts.getContainingObjectLiteralElement = getContainingObjectLiteralElement;
    /* @internal */
    function getPropertySymbolsFromContextualType(typeChecker, node) {
        var objectLiteral = node.parent;
        var contextualType = typeChecker.getContextualType(objectLiteral);
        return getPropertySymbolsFromType(contextualType, node.name);
    }
    ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType;
    /* @internal */
    function getPropertySymbolsFromType(type, propName) {
        var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName));
        if (name && type) {
            var result_10 = [];
            var symbol = type.getProperty(name);
            if (type.flags & 65536 /* Union */) {
                ts.forEach(type.types, function (t) {
                    var symbol = t.getProperty(name);
                    if (symbol) {
                        result_10.push(symbol);
                    }
                });
                return result_10;
            }
            if (symbol) {
                result_10.push(symbol);
                return result_10;
            }
        }
        return undefined;
    }
    ts.getPropertySymbolsFromType = getPropertySymbolsFromType;
    function isArgumentOfElementAccessExpression(node) {
        return node &&
            node.parent &&
            node.parent.kind === 180 /* ElementAccessExpression */ &&
            node.parent.argumentExpression === node;
    }
    /**
     * Get the path of the default library files (lib.d.ts) as distributed with the typescript
     * node package.
     * The functionality is not supported if the ts module is consumed outside of a node module.
     */
    function getDefaultLibFilePath(options) {
        // Check __dirname is defined and that we are on a node.js system.
        if (typeof __dirname !== "undefined") {
            return __dirname + ts.directorySeparator + ts.getDefaultLibFileName(options);
        }
        throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");
    }
    ts.getDefaultLibFilePath = getDefaultLibFilePath;
    ts.objectAllocator = getServicesObjectAllocator();
})(ts || (ts = {}));
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
// See LICENSE.txt in the project root for complete license information.
/// <reference path='services.ts' />
/* @internal */
var ts;
(function (ts) {
    var BreakpointResolver;
    (function (BreakpointResolver) {
        /**
         * Get the breakpoint span in given sourceFile
         */
        function spanInSourceFileAtLocation(sourceFile, position) {
            // Cannot set breakpoint in dts file
            if (sourceFile.isDeclarationFile) {
                return undefined;
            }
            var tokenAtLocation = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
            var lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
            if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
                // Get previous token if the token is returned starts on new line
                // eg: let x =10; |--- cursor is here
                //     let y = 10;
                // token at position will return let keyword on second line as the token but we would like to use
                // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
                tokenAtLocation = ts.findPrecedingToken(tokenAtLocation.pos, sourceFile);
                // It's a blank line
                if (!tokenAtLocation || sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getEnd()).line !== lineOfPosition) {
                    return undefined;
                }
            }
            // Cannot set breakpoint in ambient declarations
            if (ts.isInAmbientContext(tokenAtLocation)) {
                return undefined;
            }
            // Get the span in the node based on its syntax
            return spanInNode(tokenAtLocation);
            function textSpan(startNode, endNode) {
                var start = startNode.decorators ?
                    ts.skipTrivia(sourceFile.text, startNode.decorators.end) :
                    startNode.getStart(sourceFile);
                return ts.createTextSpanFromBounds(start, (endNode || startNode).getEnd());
            }
            function textSpanEndingAtNextToken(startNode, previousTokenToFindNextEndToken) {
                return textSpan(startNode, ts.findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent));
            }
            function spanInNodeIfStartsOnSameLine(node, otherwiseOnNode) {
                if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
                    return spanInNode(node);
                }
                return spanInNode(otherwiseOnNode);
            }
            function spanInNodeArray(nodeArray) {
                return ts.createTextSpanFromBounds(ts.skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
            }
            function spanInPreviousNode(node) {
                return spanInNode(ts.findPrecedingToken(node.pos, sourceFile));
            }
            function spanInNextNode(node) {
                return spanInNode(ts.findNextToken(node, node.parent));
            }
            function spanInNode(node) {
                if (node) {
                    switch (node.kind) {
                        case 208 /* VariableStatement */:
                            // Span on first variable declaration
                            return spanInVariableDeclaration(node.declarationList.declarations[0]);
                        case 226 /* VariableDeclaration */:
                        case 149 /* PropertyDeclaration */:
                        case 148 /* PropertySignature */:
                            return spanInVariableDeclaration(node);
                        case 146 /* Parameter */:
                            return spanInParameterDeclaration(node);
                        case 228 /* FunctionDeclaration */:
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                        case 153 /* GetAccessor */:
                        case 154 /* SetAccessor */:
                        case 152 /* Constructor */:
                        case 186 /* FunctionExpression */:
                        case 187 /* ArrowFunction */:
                            return spanInFunctionDeclaration(node);
                        case 207 /* Block */:
                            if (ts.isFunctionBlock(node)) {
                                return spanInFunctionBlock(node);
                            }
                        // falls through
                        case 234 /* ModuleBlock */:
                            return spanInBlock(node);
                        case 260 /* CatchClause */:
                            return spanInBlock(node.block);
                        case 210 /* ExpressionStatement */:
                            // span on the expression
                            return textSpan(node.expression);
                        case 219 /* ReturnStatement */:
                            // span on return keyword and expression if present
                            return textSpan(node.getChildAt(0), node.expression);
                        case 213 /* WhileStatement */:
                            // Span on while(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 212 /* DoStatement */:
                            // span in statement of the do statement
                            return spanInNode(node.statement);
                        case 225 /* DebuggerStatement */:
                            // span on debugger keyword
                            return textSpan(node.getChildAt(0));
                        case 211 /* IfStatement */:
                            // set on if(..) span
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 222 /* LabeledStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 218 /* BreakStatement */:
                        case 217 /* ContinueStatement */:
                            // On break or continue keyword and label if present
                            return textSpan(node.getChildAt(0), node.label);
                        case 214 /* ForStatement */:
                            return spanInForStatement(node);
                        case 215 /* ForInStatement */:
                            // span of for (a in ...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 216 /* ForOfStatement */:
                            // span in initializer
                            return spanInInitializerOfForLike(node);
                        case 221 /* SwitchStatement */:
                            // span on switch(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 257 /* CaseClause */:
                        case 258 /* DefaultClause */:
                            // span in first statement of the clause
                            return spanInNode(node.statements[0]);
                        case 224 /* TryStatement */:
                            // span in try block
                            return spanInBlock(node.tryBlock);
                        case 223 /* ThrowStatement */:
                            // span in throw ...
                            return textSpan(node, node.expression);
                        case 243 /* ExportAssignment */:
                            // span on export = id
                            return textSpan(node, node.expression);
                        case 237 /* ImportEqualsDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleReference);
                        case 238 /* ImportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 244 /* ExportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 233 /* ModuleDeclaration */:
                            // span on complete module if it is instantiated
                            if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        case 229 /* ClassDeclaration */:
                        case 232 /* EnumDeclaration */:
                        case 264 /* EnumMember */:
                        case 176 /* BindingElement */:
                            // span on complete node
                            return textSpan(node);
                        case 220 /* WithStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 147 /* Decorator */:
                            return spanInNodeArray(node.parent.decorators);
                        case 174 /* ObjectBindingPattern */:
                        case 175 /* ArrayBindingPattern */:
                            return spanInBindingPattern(node);
                        // No breakpoint in interface, type alias
                        case 230 /* InterfaceDeclaration */:
                        case 231 /* TypeAliasDeclaration */:
                            return undefined;
                        // Tokens:
                        case 25 /* SemicolonToken */:
                        case 1 /* EndOfFileToken */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile));
                        case 26 /* CommaToken */:
                            return spanInPreviousNode(node);
                        case 17 /* OpenBraceToken */:
                            return spanInOpenBraceToken(node);
                        case 18 /* CloseBraceToken */:
                            return spanInCloseBraceToken(node);
                        case 22 /* CloseBracketToken */:
                            return spanInCloseBracketToken(node);
                        case 19 /* OpenParenToken */:
                            return spanInOpenParenToken(node);
                        case 20 /* CloseParenToken */:
                            return spanInCloseParenToken(node);
                        case 56 /* ColonToken */:
                            return spanInColonToken(node);
                        case 29 /* GreaterThanToken */:
                        case 27 /* LessThanToken */:
                            return spanInGreaterThanOrLessThanToken(node);
                        // Keywords:
                        case 106 /* WhileKeyword */:
                            return spanInWhileKeyword(node);
                        case 82 /* ElseKeyword */:
                        case 74 /* CatchKeyword */:
                        case 87 /* FinallyKeyword */:
                            return spanInNextNode(node);
                        case 142 /* OfKeyword */:
                            return spanInOfKeyword(node);
                        default:
                            // Destructuring pattern in destructuring assignment
                            // [a, b, c] of
                            // [a, b, c] = expression
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node)) {
                                return spanInArrayLiteralOrObjectLiteralDestructuringPattern(node);
                            }
                            // Set breakpoint on identifier element of destructuring pattern
                            // a or ...c  or d: x from
                            // [a, b, ...c] or { a, b } or { d: x } from destructuring pattern
                            if ((node.kind === 71 /* Identifier */ ||
                                node.kind === 198 /* SpreadElement */ ||
                                node.kind === 261 /* PropertyAssignment */ ||
                                node.kind === 262 /* ShorthandPropertyAssignment */) &&
                                ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                return textSpan(node);
                            }
                            if (node.kind === 194 /* BinaryExpression */) {
                                var binaryExpression = node;
                                // Set breakpoint in destructuring pattern if its destructuring assignment
                                // [a, b, c] or {a, b, c} of
                                // [a, b, c] = expression or
                                // {a, b, c} = expression
                                if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) {
                                    return spanInArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left);
                                }
                                if (binaryExpression.operatorToken.kind === 58 /* EqualsToken */ &&
                                    ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) {
                                    // Set breakpoint on assignment expression element of destructuring pattern
                                    // a = expression of
                                    // [a = expression, b, c] = someExpression or
                                    // { a = expression, b, c } = someExpression
                                    return textSpan(node);
                                }
                                if (binaryExpression.operatorToken.kind === 26 /* CommaToken */) {
                                    return spanInNode(binaryExpression.left);
                                }
                            }
                            if (ts.isPartOfExpression(node)) {
                                switch (node.parent.kind) {
                                    case 212 /* DoStatement */:
                                        // Set span as if on while keyword
                                        return spanInPreviousNode(node);
                                    case 147 /* Decorator */:
                                        // Set breakpoint on the decorator emit
                                        return spanInNode(node.parent);
                                    case 214 /* ForStatement */:
                                    case 216 /* ForOfStatement */:
                                        return textSpan(node);
                                    case 194 /* BinaryExpression */:
                                        if (node.parent.operatorToken.kind === 26 /* CommaToken */) {
                                            // If this is a comma expression, the breakpoint is possible in this expression
                                            return textSpan(node);
                                        }
                                        break;
                                    case 187 /* ArrowFunction */:
                                        if (node.parent.body === node) {
                                            // If this is body of arrow function, it is allowed to have the breakpoint
                                            return textSpan(node);
                                        }
                                        break;
                                }
                            }
                            // If this is name of property assignment, set breakpoint in the initializer
                            if (node.parent.kind === 261 /* PropertyAssignment */ &&
                                node.parent.name === node &&
                                !ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
                                return spanInNode(node.parent.initializer);
                            }
                            // Breakpoint in type assertion goes to its operand
                            if (node.parent.kind === 184 /* TypeAssertionExpression */ && node.parent.type === node) {
                                return spanInNextNode(node.parent.type);
                            }
                            // return type of function go to previous token
                            if (ts.isFunctionLike(node.parent) && node.parent.type === node) {
                                return spanInPreviousNode(node);
                            }
                            // initializer of variable/parameter declaration go to previous node
                            if ((node.parent.kind === 226 /* VariableDeclaration */ ||
                                node.parent.kind === 146 /* Parameter */)) {
                                var paramOrVarDecl = node.parent;
                                if (paramOrVarDecl.initializer === node ||
                                    paramOrVarDecl.type === node ||
                                    ts.isAssignmentOperator(node.kind)) {
                                    return spanInPreviousNode(node);
                                }
                            }
                            if (node.parent.kind === 194 /* BinaryExpression */) {
                                var binaryExpression = node.parent;
                                if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left) &&
                                    (binaryExpression.right === node ||
                                        binaryExpression.operatorToken === node)) {
                                    // If initializer of destructuring assignment move to previous token
                                    return spanInPreviousNode(node);
                                }
                            }
                            // Default go to parent to set the breakpoint
                            return spanInNode(node.parent);
                    }
                }
                function textSpanFromVariableDeclaration(variableDeclaration) {
                    if (variableDeclaration.parent.kind === 227 /* VariableDeclarationList */ &&
                        variableDeclaration.parent.declarations[0] === variableDeclaration) {
                        // First declaration - include let keyword
                        return textSpan(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
                    }
                    else {
                        // Span only on this declaration
                        return textSpan(variableDeclaration);
                    }
                }
                function spanInVariableDeclaration(variableDeclaration) {
                    // If declaration of for in statement, just set the span in parent
                    if (variableDeclaration.parent.parent.kind === 215 /* ForInStatement */) {
                        return spanInNode(variableDeclaration.parent.parent);
                    }
                    // If this is a destructuring pattern, set breakpoint in binding pattern
                    if (ts.isBindingPattern(variableDeclaration.name)) {
                        return spanInBindingPattern(variableDeclaration.name);
                    }
                    // Breakpoint is possible in variableDeclaration only if there is initialization
                    // or its declaration from 'for of'
                    if (variableDeclaration.initializer ||
                        ts.hasModifier(variableDeclaration, 1 /* Export */) ||
                        variableDeclaration.parent.parent.kind === 216 /* ForOfStatement */) {
                        return textSpanFromVariableDeclaration(variableDeclaration);
                    }
                    if (variableDeclaration.parent.kind === 227 /* VariableDeclarationList */ &&
                        variableDeclaration.parent.declarations[0] !== variableDeclaration) {
                        // If we cannot set breakpoint on this declaration, set it on previous one
                        // Because the variable declaration may be binding pattern and
                        // we would like to set breakpoint in last binding element if that's the case,
                        // use preceding token instead
                        return spanInNode(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
                    }
                }
                function canHaveSpanInParameterDeclaration(parameter) {
                    // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier
                    return !!parameter.initializer || parameter.dotDotDotToken !== undefined ||
                        ts.hasModifier(parameter, 4 /* Public */ | 8 /* Private */);
                }
                function spanInParameterDeclaration(parameter) {
                    if (ts.isBindingPattern(parameter.name)) {
                        // Set breakpoint in binding pattern
                        return spanInBindingPattern(parameter.name);
                    }
                    else if (canHaveSpanInParameterDeclaration(parameter)) {
                        return textSpan(parameter);
                    }
                    else {
                        var functionDeclaration = parameter.parent;
                        var indexOfParameter = ts.indexOf(functionDeclaration.parameters, parameter);
                        if (indexOfParameter) {
                            // Not a first parameter, go to previous parameter
                            return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]);
                        }
                        else {
                            // Set breakpoint in the function declaration body
                            return spanInNode(functionDeclaration.body);
                        }
                    }
                }
                function canFunctionHaveSpanInWholeDeclaration(functionDeclaration) {
                    return ts.hasModifier(functionDeclaration, 1 /* Export */) ||
                        (functionDeclaration.parent.kind === 229 /* ClassDeclaration */ && functionDeclaration.kind !== 152 /* Constructor */);
                }
                function spanInFunctionDeclaration(functionDeclaration) {
                    // No breakpoints in the function signature
                    if (!functionDeclaration.body) {
                        return undefined;
                    }
                    if (canFunctionHaveSpanInWholeDeclaration(functionDeclaration)) {
                        // Set the span on whole function declaration
                        return textSpan(functionDeclaration);
                    }
                    // Set span in function body
                    return spanInNode(functionDeclaration.body);
                }
                function spanInFunctionBlock(block) {
                    var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken();
                    if (canFunctionHaveSpanInWholeDeclaration(block.parent)) {
                        return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock);
                    }
                    return spanInNode(nodeForSpanInBlock);
                }
                function spanInBlock(block) {
                    switch (block.parent.kind) {
                        case 233 /* ModuleDeclaration */:
                            if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        // Set on parent if on same line otherwise on first statement
                        case 213 /* WhileStatement */:
                        case 211 /* IfStatement */:
                        case 215 /* ForInStatement */:
                            return spanInNodeIfStartsOnSameLine(block.parent, block.statements[0]);
                        // Set span on previous token if it starts on same line otherwise on the first statement of the block
                        case 214 /* ForStatement */:
                        case 216 /* ForOfStatement */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(block.pos, sourceFile, block.parent), block.statements[0]);
                    }
                    // Default action is to set on first statement
                    return spanInNode(block.statements[0]);
                }
                function spanInInitializerOfForLike(forLikeStatement) {
                    if (forLikeStatement.initializer.kind === 227 /* VariableDeclarationList */) {
                        // Declaration list - set breakpoint in first declaration
                        var variableDeclarationList = forLikeStatement.initializer;
                        if (variableDeclarationList.declarations.length > 0) {
                            return spanInNode(variableDeclarationList.declarations[0]);
                        }
                    }
                    else {
                        // Expression - set breakpoint in it
                        return spanInNode(forLikeStatement.initializer);
                    }
                }
                function spanInForStatement(forStatement) {
                    if (forStatement.initializer) {
                        return spanInInitializerOfForLike(forStatement);
                    }
                    if (forStatement.condition) {
                        return textSpan(forStatement.condition);
                    }
                    if (forStatement.incrementor) {
                        return textSpan(forStatement.incrementor);
                    }
                }
                function spanInBindingPattern(bindingPattern) {
                    // Set breakpoint in first binding element
                    var firstBindingElement = ts.forEach(bindingPattern.elements, function (element) { return element.kind !== 200 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Empty binding pattern of binding element, set breakpoint on binding element
                    if (bindingPattern.parent.kind === 176 /* BindingElement */) {
                        return textSpan(bindingPattern.parent);
                    }
                    // Variable declaration is used as the span
                    return textSpanFromVariableDeclaration(bindingPattern.parent);
                }
                function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node) {
                    ts.Debug.assert(node.kind !== 175 /* ArrayBindingPattern */ && node.kind !== 174 /* ObjectBindingPattern */);
                    var elements = node.kind === 177 /* ArrayLiteralExpression */ ?
                        node.elements :
                        node.properties;
                    var firstBindingElement = ts.forEach(elements, function (element) { return element.kind !== 200 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Could be ArrayLiteral from destructuring assignment or
                    // just nested element in another destructuring assignment
                    // set breakpoint on assignment when parent is destructuring assignment
                    // Otherwise set breakpoint for this element
                    return textSpan(node.parent.kind === 194 /* BinaryExpression */ ? node.parent : node);
                }
                // Tokens:
                function spanInOpenBraceToken(node) {
                    switch (node.parent.kind) {
                        case 232 /* EnumDeclaration */:
                            var enumDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile));
                        case 229 /* ClassDeclaration */:
                            var classDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
                        case 235 /* CaseBlock */:
                            return spanInNodeIfStartsOnSameLine(node.parent.parent, node.parent.clauses[0]);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInCloseBraceToken(node) {
                    switch (node.parent.kind) {
                        case 234 /* ModuleBlock */:
                            // If this is not an instantiated module block, no bp span
                            if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        case 232 /* EnumDeclaration */:
                        case 229 /* ClassDeclaration */:
                            // Span on close brace token
                            return textSpan(node);
                        case 207 /* Block */:
                            if (ts.isFunctionBlock(node.parent)) {
                                // Span on close brace token
                                return textSpan(node);
                            }
                        // falls through
                        case 260 /* CatchClause */:
                            return spanInNode(ts.lastOrUndefined(node.parent.statements));
                        case 235 /* CaseBlock */:
                            // breakpoint in last statement of the last clause
                            var caseBlock = node.parent;
                            var lastClause = ts.lastOrUndefined(caseBlock.clauses);
                            if (lastClause) {
                                return spanInNode(ts.lastOrUndefined(lastClause.statements));
                            }
                            return undefined;
                        case 174 /* ObjectBindingPattern */:
                            // Breakpoint in last binding element or binding pattern if it contains no elements
                            var bindingPattern = node.parent;
                            return spanInNode(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
                        // Default to parent node
                        default:
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                // Breakpoint in last binding element or binding pattern if it contains no elements
                                var objectLiteral = node.parent;
                                return textSpan(ts.lastOrUndefined(objectLiteral.properties) || objectLiteral);
                            }
                            return spanInNode(node.parent);
                    }
                }
                function spanInCloseBracketToken(node) {
                    switch (node.parent.kind) {
                        case 175 /* ArrayBindingPattern */:
                            // Breakpoint in last binding element or binding pattern if it contains no elements
                            var bindingPattern = node.parent;
                            return textSpan(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
                        default:
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                // Breakpoint in last binding element or binding pattern if it contains no elements
                                var arrayLiteral = node.parent;
                                return textSpan(ts.lastOrUndefined(arrayLiteral.elements) || arrayLiteral);
                            }
                            // Default to parent node
                            return spanInNode(node.parent);
                    }
                }
                function spanInOpenParenToken(node) {
                    if (node.parent.kind === 212 /* DoStatement */ || // Go to while keyword and do action instead
                        node.parent.kind === 181 /* CallExpression */ ||
                        node.parent.kind === 182 /* NewExpression */) {
                        return spanInPreviousNode(node);
                    }
                    if (node.parent.kind === 185 /* ParenthesizedExpression */) {
                        return spanInNextNode(node);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInCloseParenToken(node) {
                    // Is this close paren token of parameter list, set span in previous token
                    switch (node.parent.kind) {
                        case 186 /* FunctionExpression */:
                        case 228 /* FunctionDeclaration */:
                        case 187 /* ArrowFunction */:
                        case 151 /* MethodDeclaration */:
                        case 150 /* MethodSignature */:
                        case 153 /* GetAccessor */:
                        case 154 /* SetAccessor */:
                        case 152 /* Constructor */:
                        case 213 /* WhileStatement */:
                        case 212 /* DoStatement */:
                        case 214 /* ForStatement */:
                        case 216 /* ForOfStatement */:
                        case 181 /* CallExpression */:
                        case 182 /* NewExpression */:
                        case 185 /* ParenthesizedExpression */:
                            return spanInPreviousNode(node);
                        // Default to parent node
                        default:
                            return spanInNode(node.parent);
                    }
                }
                function spanInColonToken(node) {
                    // Is this : specifying return annotation of the function declaration
                    if (ts.isFunctionLike(node.parent) ||
                        node.parent.kind === 261 /* PropertyAssignment */ ||
                        node.parent.kind === 146 /* Parameter */) {
                        return spanInPreviousNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInGreaterThanOrLessThanToken(node) {
                    if (node.parent.kind === 184 /* TypeAssertionExpression */) {
                        return spanInNextNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInWhileKeyword(node) {
                    if (node.parent.kind === 212 /* DoStatement */) {
                        // Set span on while expression
                        return textSpanEndingAtNextToken(node, node.parent.expression);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInOfKeyword(node) {
                    if (node.parent.kind === 216 /* ForOfStatement */) {
                        // Set using next token
                        return spanInNextNode(node);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
            }
        }
        BreakpointResolver.spanInSourceFileAtLocation = spanInSourceFileAtLocation;
    })(BreakpointResolver = ts.BreakpointResolver || (ts.BreakpointResolver = {}));
})(ts || (ts = {}));
/// <reference path="..\compiler\transformer.ts"/>
/// <reference path="transpile.ts"/>
var ts;
(function (ts) {
    /**
     * Transform one or more nodes using the supplied transformers.
     * @param source A single `Node` or an array of `Node` objects.
     * @param transformers An array of `TransformerFactory` callbacks used to process the transformation.
     * @param compilerOptions Optional compiler options.
     */
    function transform(source, transformers, compilerOptions) {
        var diagnostics = [];
        compilerOptions = ts.fixupCompilerOptions(compilerOptions, diagnostics);
        var nodes = ts.isArray(source) ? source : [source];
        var result = ts.transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
        result.diagnostics = ts.concatenate(result.diagnostics, diagnostics);
        return result;
    }
    ts.transform = transform;
})(ts || (ts = {}));
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/// <reference path='services.ts' />
/* @internal */
var debugObjectHost = (function () { return this; })();
// We need to use 'null' to interface with the managed side.
/* tslint:disable:no-null-keyword */
/* tslint:disable:no-in-operator */
/* @internal */
var ts;
(function (ts) {
    function logInternalError(logger, err) {
        if (logger) {
            logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message);
        }
    }
    var ScriptSnapshotShimAdapter = /** @class */ (function () {
        function ScriptSnapshotShimAdapter(scriptSnapshotShim) {
            this.scriptSnapshotShim = scriptSnapshotShim;
        }
        ScriptSnapshotShimAdapter.prototype.getText = function (start, end) {
            return this.scriptSnapshotShim.getText(start, end);
        };
        ScriptSnapshotShimAdapter.prototype.getLength = function () {
            return this.scriptSnapshotShim.getLength();
        };
        ScriptSnapshotShimAdapter.prototype.getChangeRange = function (oldSnapshot) {
            var oldSnapshotShim = oldSnapshot;
            var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
            if (encoded === null) {
                return null;
            }
            var decoded = JSON.parse(encoded);
            return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength);
        };
        ScriptSnapshotShimAdapter.prototype.dispose = function () {
            // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments
            // 'in' does not have this effect
            if ("dispose" in this.scriptSnapshotShim) {
                this.scriptSnapshotShim.dispose();
            }
        };
        return ScriptSnapshotShimAdapter;
    }());
    var LanguageServiceShimHostAdapter = /** @class */ (function () {
        function LanguageServiceShimHostAdapter(shimHost) {
            var _this = this;
            this.shimHost = shimHost;
            this.loggingEnabled = false;
            this.tracingEnabled = false;
            // if shimHost is a COM object then property check will become method call with no arguments.
            // 'in' does not have this effect.
            if ("getModuleResolutionsForFile" in this.shimHost) {
                this.resolveModuleNames = function (moduleNames, containingFile) {
                    var resolutionsInFile = JSON.parse(_this.shimHost.getModuleResolutionsForFile(containingFile));
                    return ts.map(moduleNames, function (name) {
                        var result = ts.getProperty(resolutionsInFile, name);
                        return result ? { resolvedFileName: result, extension: ts.extensionFromPath(result), isExternalLibraryImport: false } : undefined;
                    });
                };
            }
            if ("directoryExists" in this.shimHost) {
                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
            }
            if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) {
                this.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) {
                    var typeDirectivesForFile = JSON.parse(_this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile));
                    return ts.map(typeDirectiveNames, function (name) { return ts.getProperty(typeDirectivesForFile, name); });
                };
            }
        }
        LanguageServiceShimHostAdapter.prototype.log = function (s) {
            if (this.loggingEnabled) {
                this.shimHost.log(s);
            }
        };
        LanguageServiceShimHostAdapter.prototype.trace = function (s) {
            if (this.tracingEnabled) {
                this.shimHost.trace(s);
            }
        };
        LanguageServiceShimHostAdapter.prototype.error = function (s) {
            this.shimHost.error(s);
        };
        LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () {
            if (!this.shimHost.getProjectVersion) {
                // shimmed host does not support getProjectVersion
                return undefined;
            }
            return this.shimHost.getProjectVersion();
        };
        LanguageServiceShimHostAdapter.prototype.getTypeRootsVersion = function () {
            if (!this.shimHost.getTypeRootsVersion) {
                return 0;
            }
            return this.shimHost.getTypeRootsVersion();
        };
        LanguageServiceShimHostAdapter.prototype.useCaseSensitiveFileNames = function () {
            return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
        };
        LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () {
            var settingsJson = this.shimHost.getCompilationSettings();
            if (settingsJson === null || settingsJson === "") {
                throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
            }
            var compilerOptions = JSON.parse(settingsJson);
            // permit language service to handle all files (filtering should be performed on the host side)
            compilerOptions.allowNonTsExtensions = true;
            return compilerOptions;
        };
        LanguageServiceShimHostAdapter.prototype.getScriptFileNames = function () {
            var encoded = this.shimHost.getScriptFileNames();
            return this.files = JSON.parse(encoded);
        };
        LanguageServiceShimHostAdapter.prototype.getScriptSnapshot = function (fileName) {
            var scriptSnapshot = this.shimHost.getScriptSnapshot(fileName);
            return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot);
        };
        LanguageServiceShimHostAdapter.prototype.getScriptKind = function (fileName) {
            if ("getScriptKind" in this.shimHost) {
                return this.shimHost.getScriptKind(fileName);
            }
            else {
                return 0 /* Unknown */;
            }
        };
        LanguageServiceShimHostAdapter.prototype.getScriptVersion = function (fileName) {
            return this.shimHost.getScriptVersion(fileName);
        };
        LanguageServiceShimHostAdapter.prototype.getLocalizedDiagnosticMessages = function () {
            var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
            if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") {
                return null;
            }
            try {
                return JSON.parse(diagnosticMessagesJson);
            }
            catch (e) {
                this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
                return null;
            }
        };
        LanguageServiceShimHostAdapter.prototype.getCancellationToken = function () {
            var hostCancellationToken = this.shimHost.getCancellationToken();
            return new ts.ThrottledCancellationToken(hostCancellationToken);
        };
        LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () {
            return this.shimHost.getCurrentDirectory();
        };
        LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) {
            return JSON.parse(this.shimHost.getDirectories(path));
        };
        LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) {
            return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
        };
        LanguageServiceShimHostAdapter.prototype.readDirectory = function (path, extensions, exclude, include, depth) {
            var pattern = ts.getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
            return JSON.parse(this.shimHost.readDirectory(path, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
        };
        LanguageServiceShimHostAdapter.prototype.readFile = function (path, encoding) {
            return this.shimHost.readFile(path, encoding);
        };
        LanguageServiceShimHostAdapter.prototype.fileExists = function (path) {
            return this.shimHost.fileExists(path);
        };
        return LanguageServiceShimHostAdapter;
    }());
    ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter;
    var CoreServicesShimHostAdapter = /** @class */ (function () {
        function CoreServicesShimHostAdapter(shimHost) {
            var _this = this;
            this.shimHost = shimHost;
            this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
            if ("directoryExists" in this.shimHost) {
                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
            }
            if ("realpath" in this.shimHost) {
                this.realpath = function (path) { return _this.shimHost.realpath(path); };
            }
        }
        CoreServicesShimHostAdapter.prototype.readDirectory = function (rootDir, extensions, exclude, include, depth) {
            var pattern = ts.getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
            return JSON.parse(this.shimHost.readDirectory(rootDir, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
        };
        CoreServicesShimHostAdapter.prototype.fileExists = function (fileName) {
            return this.shimHost.fileExists(fileName);
        };
        CoreServicesShimHostAdapter.prototype.readFile = function (fileName) {
            return this.shimHost.readFile(fileName);
        };
        CoreServicesShimHostAdapter.prototype.getDirectories = function (path) {
            return JSON.parse(this.shimHost.getDirectories(path));
        };
        return CoreServicesShimHostAdapter;
    }());
    ts.CoreServicesShimHostAdapter = CoreServicesShimHostAdapter;
    function simpleForwardCall(logger, actionDescription, action, logPerformance) {
        var start;
        if (logPerformance) {
            logger.log(actionDescription);
            start = ts.timestamp();
        }
        var result = action();
        if (logPerformance) {
            var end = ts.timestamp();
            logger.log(actionDescription + " completed in " + (end - start) + " msec");
            if (ts.isString(result)) {
                var str = result;
                if (str.length > 128) {
                    str = str.substring(0, 128) + "...";
                }
                logger.log("  result.length=" + str.length + ", result='" + JSON.stringify(str) + "'");
            }
        }
        return result;
    }
    function forwardJSONCall(logger, actionDescription, action, logPerformance) {
        return forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance);
    }
    function forwardCall(logger, actionDescription, returnJson, action, logPerformance) {
        try {
            var result = simpleForwardCall(logger, actionDescription, action, logPerformance);
            return returnJson ? JSON.stringify({ result: result }) : result;
        }
        catch (err) {
            if (err instanceof ts.OperationCanceledException) {
                return JSON.stringify({ canceled: true });
            }
            logInternalError(logger, err);
            err.description = actionDescription;
            return JSON.stringify({ error: err });
        }
    }
    var ShimBase = /** @class */ (function () {
        function ShimBase(factory) {
            this.factory = factory;
            factory.registerShim(this);
        }
        ShimBase.prototype.dispose = function (_dummy) {
            this.factory.unregisterShim(this);
        };
        return ShimBase;
    }());
    function realizeDiagnostics(diagnostics, newLine) {
        return diagnostics.map(function (d) { return realizeDiagnostic(d, newLine); });
    }
    ts.realizeDiagnostics = realizeDiagnostics;
    function realizeDiagnostic(diagnostic, newLine) {
        return {
            message: ts.flattenDiagnosticMessageText(diagnostic.messageText, newLine),
            start: diagnostic.start,
            length: diagnostic.length,
            /// TODO: no need for the tolowerCase call
            category: ts.DiagnosticCategory[diagnostic.category].toLowerCase(),
            code: diagnostic.code
        };
    }
    var LanguageServiceShimObject = /** @class */ (function (_super) {
        __extends(LanguageServiceShimObject, _super);
        function LanguageServiceShimObject(factory, host, languageService) {
            var _this = _super.call(this, factory) || this;
            _this.host = host;
            _this.languageService = languageService;
            _this.logPerformance = false;
            _this.logger = _this.host;
            return _this;
        }
        LanguageServiceShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
        };
        /// DISPOSE
        /**
         * Ensure (almost) deterministic release of internal Javascript resources when
         * some external native objects holds onto us (e.g. Com/Interop).
         */
        LanguageServiceShimObject.prototype.dispose = function (dummy) {
            this.logger.log("dispose()");
            this.languageService.dispose();
            this.languageService = null;
            // force a GC
            if (debugObjectHost && debugObjectHost.CollectGarbage) {
                debugObjectHost.CollectGarbage();
                this.logger.log("CollectGarbage()");
            }
            this.logger = null;
            _super.prototype.dispose.call(this, dummy);
        };
        /// REFRESH
        /**
         * Update the list of scripts known to the compiler
         */
        LanguageServiceShimObject.prototype.refresh = function (throwOnError) {
            this.forwardJSONCall("refresh(" + throwOnError + ")", function () { return null; });
        };
        LanguageServiceShimObject.prototype.cleanupSemanticCache = function () {
            var _this = this;
            this.forwardJSONCall("cleanupSemanticCache()", function () {
                _this.languageService.cleanupSemanticCache();
                return null;
            });
        };
        LanguageServiceShimObject.prototype.realizeDiagnostics = function (diagnostics) {
            var newLine = ts.getNewLineOrDefaultFromHost(this.host);
            return ts.realizeDiagnostics(diagnostics, newLine);
        };
        LanguageServiceShimObject.prototype.getSyntacticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSyntacticClassifications(fileName, ts.createTextSpan(start, length)); });
        };
        LanguageServiceShimObject.prototype.getSemanticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSemanticClassifications(fileName, ts.createTextSpan(start, length)); });
        };
        LanguageServiceShimObject.prototype.getEncodedSyntacticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getEncodedSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", 
            // directly serialize the spans out to a string.  This is much faster to decode
            // on the managed side versus a full JSON array.
            function () { return convertClassifications(_this.languageService.getEncodedSyntacticClassifications(fileName, ts.createTextSpan(start, length))); });
        };
        LanguageServiceShimObject.prototype.getEncodedSemanticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getEncodedSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", 
            // directly serialize the spans out to a string.  This is much faster to decode
            // on the managed side versus a full JSON array.
            function () { return convertClassifications(_this.languageService.getEncodedSemanticClassifications(fileName, ts.createTextSpan(start, length))); });
        };
        LanguageServiceShimObject.prototype.getSyntacticDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSyntacticDiagnostics('" + fileName + "')", function () {
                var diagnostics = _this.languageService.getSyntacticDiagnostics(fileName);
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        LanguageServiceShimObject.prototype.getSemanticDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSemanticDiagnostics('" + fileName + "')", function () {
                var diagnostics = _this.languageService.getSemanticDiagnostics(fileName);
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        LanguageServiceShimObject.prototype.getCompilerOptionsDiagnostics = function () {
            var _this = this;
            return this.forwardJSONCall("getCompilerOptionsDiagnostics()", function () {
                var diagnostics = _this.languageService.getCompilerOptionsDiagnostics();
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        /// QUICKINFO
        /**
         * Computes a string representation of the type at the requested position
         * in the active file.
         */
        LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); });
        };
        /// NAMEORDOTTEDNAMESPAN
        /**
         * Computes span information of the name or dotted name at the requested position
         * in the active file.
         */
        LanguageServiceShimObject.prototype.getNameOrDottedNameSpan = function (fileName, startPos, endPos) {
            var _this = this;
            return this.forwardJSONCall("getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")", function () { return _this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos); });
        };
        /**
         * STATEMENTSPAN
         * Computes span information of statement at the requested position in the active file.
         */
        LanguageServiceShimObject.prototype.getBreakpointStatementAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getBreakpointStatementAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBreakpointStatementAtPosition(fileName, position); });
        };
        /// SIGNATUREHELP
        LanguageServiceShimObject.prototype.getSignatureHelpItems = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getSignatureHelpItems('" + fileName + "', " + position + ")", function () { return _this.languageService.getSignatureHelpItems(fileName, position); });
        };
        /// GOTO DEFINITION
        /**
         * Computes the definition location and file for the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getDefinitionAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAtPosition(fileName, position); });
        };
        /// GOTO Type
        /**
         * Computes the definition location of the type of the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getTypeDefinitionAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getTypeDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getTypeDefinitionAtPosition(fileName, position); });
        };
        /// GOTO Implementation
        /**
         * Computes the implementation location of the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getImplementationAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getImplementationAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getImplementationAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getRenameInfo = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getRenameInfo('" + fileName + "', " + position + ")", function () { return _this.languageService.getRenameInfo(fileName, position); });
        };
        LanguageServiceShimObject.prototype.findRenameLocations = function (fileName, position, findInStrings, findInComments) {
            var _this = this;
            return this.forwardJSONCall("findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ")", function () { return _this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments); });
        };
        /// GET BRACE MATCHING
        LanguageServiceShimObject.prototype.getBraceMatchingAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getBraceMatchingAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBraceMatchingAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.isValidBraceCompletionAtPosition = function (fileName, position, openingBrace) {
            var _this = this;
            return this.forwardJSONCall("isValidBraceCompletionAtPosition('" + fileName + "', " + position + ", " + openingBrace + ")", function () { return _this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace); });
        };
        LanguageServiceShimObject.prototype.getSpanOfEnclosingComment = function (fileName, position, onlyMultiLine) {
            var _this = this;
            return this.forwardJSONCall("getSpanOfEnclosingComment('" + fileName + "', " + position + ")", function () { return _this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine); });
        };
        /// GET SMART INDENT
        LanguageServiceShimObject.prototype.getIndentationAtPosition = function (fileName, position, options /*Services.EditorOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getIndentationAtPosition('" + fileName + "', " + position + ")", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getIndentationAtPosition(fileName, position, localOptions);
            });
        };
        /// GET REFERENCES
        LanguageServiceShimObject.prototype.getReferencesAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getReferencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getReferencesAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.findReferences = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("findReferences('" + fileName + "', " + position + ")", function () { return _this.languageService.findReferences(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getOccurrencesAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getOccurrencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getOccurrencesAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getDocumentHighlights = function (fileName, position, filesToSearch) {
            var _this = this;
            return this.forwardJSONCall("getDocumentHighlights('" + fileName + "', " + position + ")", function () {
                var results = _this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch));
                // workaround for VS document highlighting issue - keep only items from the initial file
                var normalizedName = ts.normalizeSlashes(fileName).toLowerCase();
                return ts.filter(results, function (r) { return ts.normalizeSlashes(r.fileName).toLowerCase() === normalizedName; });
            });
        };
        /// COMPLETION LISTS
        /**
         * Get a string based representation of the completions
         * to provide at the given source position and providing a member completion
         * list if requested.
         */
        LanguageServiceShimObject.prototype.getCompletionsAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getCompletionsAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getCompletionsAtPosition(fileName, position); });
        };
        /** Get a string based representation of a completion list entry details */
        LanguageServiceShimObject.prototype.getCompletionEntryDetails = function (fileName, position, entryName, options /*Services.FormatCodeOptions*/, source) {
            var _this = this;
            return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", '" + entryName + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsForRange = function (fileName, start, end, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsForDocument = function (fileName, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsForDocument('" + fileName + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsForDocument(fileName, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsAfterKeystroke = function (fileName, position, key, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getDocCommentTemplateAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDocCommentTemplateAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDocCommentTemplateAtPosition(fileName, position); });
        };
        /// NAVIGATE TO
        /** Return a list of symbols that are interesting to navigate to */
        LanguageServiceShimObject.prototype.getNavigateToItems = function (searchValue, maxResultCount, fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigateToItems('" + searchValue + "', " + maxResultCount + ", " + fileName + ")", function () { return _this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName); });
        };
        LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () { return _this.languageService.getNavigationBarItems(fileName); });
        };
        LanguageServiceShimObject.prototype.getNavigationTree = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); });
        };
        LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); });
        };
        LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) {
            var _this = this;
            return this.forwardJSONCall("getTodoComments('" + fileName + "')", function () { return _this.languageService.getTodoComments(fileName, JSON.parse(descriptors)); });
        };
        /// Emit
        LanguageServiceShimObject.prototype.getEmitOutput = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getEmitOutput('" + fileName + "')", function () { return _this.languageService.getEmitOutput(fileName); });
        };
        LanguageServiceShimObject.prototype.getEmitOutputObject = function (fileName) {
            var _this = this;
            return forwardCall(this.logger, "getEmitOutput('" + fileName + "')", 
            /*returnJson*/ false, function () { return _this.languageService.getEmitOutput(fileName); }, this.logPerformance);
        };
        return LanguageServiceShimObject;
    }(ShimBase));
    function convertClassifications(classifications) {
        return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState };
    }
    var ClassifierShimObject = /** @class */ (function (_super) {
        __extends(ClassifierShimObject, _super);
        function ClassifierShimObject(factory, logger) {
            var _this = _super.call(this, factory) || this;
            _this.logger = logger;
            _this.logPerformance = false;
            _this.classifier = ts.createClassifier();
            return _this;
        }
        ClassifierShimObject.prototype.getEncodedLexicalClassifications = function (text, lexState, syntacticClassifierAbsent) {
            var _this = this;
            return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", function () { return convertClassifications(_this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)); }, this.logPerformance);
        };
        /// COLORIZATION
        ClassifierShimObject.prototype.getClassificationsForLine = function (text, lexState, classifyKeywordsInGenerics) {
            var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
            var result = "";
            for (var _i = 0, _a = classification.entries; _i < _a.length; _i++) {
                var item = _a[_i];
                result += item.length + "\n";
                result += item.classification + "\n";
            }
            result += classification.finalLexState;
            return result;
        };
        return ClassifierShimObject;
    }(ShimBase));
    var CoreServicesShimObject = /** @class */ (function (_super) {
        __extends(CoreServicesShimObject, _super);
        function CoreServicesShimObject(factory, logger, host) {
            var _this = _super.call(this, factory) || this;
            _this.logger = logger;
            _this.host = host;
            _this.logPerformance = false;
            return _this;
        }
        CoreServicesShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
        };
        CoreServicesShimObject.prototype.resolveModuleName = function (fileName, moduleName, compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("resolveModuleName('" + fileName + "')", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                var result = ts.resolveModuleName(moduleName, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
                var resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined;
                if (result.resolvedModule && result.resolvedModule.extension !== ".ts" /* Ts */ && result.resolvedModule.extension !== ".tsx" /* Tsx */ && result.resolvedModule.extension !== ".d.ts" /* Dts */) {
                    resolvedFileName = undefined;
                }
                return {
                    resolvedFileName: resolvedFileName,
                    failedLookupLocations: result.failedLookupLocations
                };
            });
        };
        CoreServicesShimObject.prototype.resolveTypeReferenceDirective = function (fileName, typeReferenceDirective, compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("resolveTypeReferenceDirective(" + fileName + ")", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                var result = ts.resolveTypeReferenceDirective(typeReferenceDirective, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
                return {
                    resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined,
                    primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true,
                    failedLookupLocations: result.failedLookupLocations
                };
            });
        };
        CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
            var _this = this;
            return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
                // for now treat files as JavaScript
                var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
                return {
                    referencedFiles: _this.convertFileReferences(result.referencedFiles),
                    importedFiles: _this.convertFileReferences(result.importedFiles),
                    ambientExternalModules: result.ambientExternalModules,
                    isLibFile: result.isLibFile,
                    typeReferenceDirectives: _this.convertFileReferences(result.typeReferenceDirectives)
                };
            });
        };
        CoreServicesShimObject.prototype.getAutomaticTypeDirectiveNames = function (compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("getAutomaticTypeDirectiveNames('" + compilerOptionsJson + "')", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                return ts.getAutomaticTypeDirectiveNames(compilerOptions, _this.host);
            });
        };
        CoreServicesShimObject.prototype.convertFileReferences = function (refs) {
            if (!refs) {
                return undefined;
            }
            var result = [];
            for (var _i = 0, refs_2 = refs; _i < refs_2.length; _i++) {
                var ref = refs_2[_i];
                result.push({
                    path: ts.normalizeSlashes(ref.fileName),
                    position: ref.pos,
                    length: ref.end - ref.pos
                });
            }
            return result;
        };
        CoreServicesShimObject.prototype.getTSConfigFileInfo = function (fileName, sourceTextSnapshot) {
            var _this = this;
            return this.forwardJSONCall("getTSConfigFileInfo('" + fileName + "')", function () {
                var text = sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength());
                var result = ts.parseJsonText(fileName, text);
                var normalizedFileName = ts.normalizeSlashes(fileName);
                var configFile = ts.parseJsonSourceFileConfigFileContent(result, _this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
                return {
                    options: configFile.options,
                    typeAcquisition: configFile.typeAcquisition,
                    files: configFile.fileNames,
                    raw: configFile.raw,
                    errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n")
                };
            });
        };
        CoreServicesShimObject.prototype.getDefaultCompilationSettings = function () {
            return this.forwardJSONCall("getDefaultCompilationSettings()", function () { return ts.getDefaultCompilerOptions(); });
        };
        CoreServicesShimObject.prototype.discoverTypings = function (discoverTypingsJson) {
            var _this = this;
            var getCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false);
            return this.forwardJSONCall("discoverTypings()", function () {
                var info = JSON.parse(discoverTypingsJson);
                if (_this.safeList === undefined) {
                    _this.safeList = ts.JsTyping.loadSafeList(_this.host, ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName));
                }
                return ts.JsTyping.discoverTypings(_this.host, function (msg) { return _this.logger.log(msg); }, info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), _this.safeList, info.packageNameToTypingLocation, info.typeAcquisition, info.unresolvedImports);
            });
        };
        return CoreServicesShimObject;
    }(ShimBase));
    var TypeScriptServicesFactory = /** @class */ (function () {
        function TypeScriptServicesFactory() {
            this._shims = [];
        }
        /*
         * Returns script API version.
         */
        TypeScriptServicesFactory.prototype.getServicesVersion = function () {
            return ts.servicesVersion;
        };
        TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
            try {
                if (this.documentRegistry === undefined) {
                    this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
                }
                var hostAdapter = new LanguageServiceShimHostAdapter(host);
                var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry);
                return new LanguageServiceShimObject(this, host, languageService);
            }
            catch (err) {
                logInternalError(host, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.createClassifierShim = function (logger) {
            try {
                return new ClassifierShimObject(this, logger);
            }
            catch (err) {
                logInternalError(logger, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.createCoreServicesShim = function (host) {
            try {
                var adapter = new CoreServicesShimHostAdapter(host);
                return new CoreServicesShimObject(this, host, adapter);
            }
            catch (err) {
                logInternalError(host, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.close = function () {
            // Forget all the registered shims
            ts.clear(this._shims);
            this.documentRegistry = undefined;
        };
        TypeScriptServicesFactory.prototype.registerShim = function (shim) {
            this._shims.push(shim);
        };
        TypeScriptServicesFactory.prototype.unregisterShim = function (shim) {
            for (var i = 0; i < this._shims.length; i++) {
                if (this._shims[i] === shim) {
                    delete this._shims[i];
                    return;
                }
            }
            throw new Error("Invalid operation");
        };
        return TypeScriptServicesFactory;
    }());
    ts.TypeScriptServicesFactory = TypeScriptServicesFactory;
    if (typeof module !== "undefined" && module.exports) {
        module.exports = ts;
    }
})(ts || (ts = {}));
/* tslint:enable:no-in-operator */
/* tslint:enable:no-null */
/// TODO: this is used by VS, clean this up on both sides of the interface
/* @internal */
var TypeScript;
(function (TypeScript) {
    var Services;
    (function (Services) {
        Services.TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
    })(Services = TypeScript.Services || (TypeScript.Services = {}));
})(TypeScript || (TypeScript = {}));
// 'toolsVersion' gets consumed by the managed side, so it's not unused.
// TODO: it should be moved into a namespace though.
/* @internal */
var toolsVersion = "2.6";
